Print this page
6583 remove whole-process swapping

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/disp/ts.c
          +++ new/usr/src/uts/common/disp/ts.c
↓ open down ↓ 194 lines elided ↑ open up ↑
 195  195  static int      ts_donice(kthread_t *, cred_t *, int, int *);
 196  196  static int      ts_doprio(kthread_t *, cred_t *, int, int *);
 197  197  static void     ts_exitclass(void *);
 198  198  static int      ts_canexit(kthread_t *, cred_t *);
 199  199  static void     ts_forkret(kthread_t *, kthread_t *);
 200  200  static void     ts_nullsys();
 201  201  static void     ts_parmsget(kthread_t *, void *);
 202  202  static void     ts_preempt(kthread_t *);
 203  203  static void     ts_setrun(kthread_t *);
 204  204  static void     ts_sleep(kthread_t *);
 205      -static pri_t    ts_swapin(kthread_t *, int);
 206      -static pri_t    ts_swapout(kthread_t *, int);
 207  205  static void     ts_tick(kthread_t *);
 208  206  static void     ts_trapret(kthread_t *);
 209  207  static void     ts_update(void *);
 210  208  static int      ts_update_list(int);
 211  209  static void     ts_wakeup(kthread_t *);
 212  210  static pri_t    ts_globpri(kthread_t *);
 213  211  static void     ts_yield(kthread_t *);
 214  212  extern tsdpent_t *ts_getdptbl(void);
 215  213  extern pri_t    *ts_getkmdpris(void);
 216  214  extern pri_t    td_getmaxumdpri(void);
↓ open down ↓ 37 lines elided ↑ open up ↑
 254  252          ts_exitclass,
 255  253          ts_canexit,
 256  254          ts_fork,
 257  255          ts_forkret,
 258  256          ts_parmsget,
 259  257          ts_parmsset,
 260  258          ts_nullsys,     /* stop */
 261  259          ts_exit,
 262  260          ts_nullsys,     /* active */
 263  261          ts_nullsys,     /* inactive */
 264      -        ts_swapin,
 265      -        ts_swapout,
 266  262          ts_trapret,
 267  263          ts_preempt,
 268  264          ts_setrun,
 269  265          ts_sleep,
 270  266          ts_tick,
 271  267          ts_wakeup,
 272  268          ts_donice,
 273  269          ts_globpri,
 274  270          ts_nullsys,     /* set_process_group */
 275  271          ts_yield,
↓ open down ↓ 23 lines elided ↑ open up ↑
 299  295          ts_exitclass,
 300  296          ts_canexit,
 301  297          ts_fork,
 302  298          ts_forkret,
 303  299          ia_parmsget,
 304  300          ia_parmsset,
 305  301          ts_nullsys,     /* stop */
 306  302          ts_exit,
 307  303          ts_nullsys,     /* active */
 308  304          ts_nullsys,     /* inactive */
 309      -        ts_swapin,
 310      -        ts_swapout,
 311  305          ts_trapret,
 312  306          ts_preempt,
 313  307          ts_setrun,
 314  308          ts_sleep,
 315  309          ts_tick,
 316  310          ts_wakeup,
 317  311          ts_donice,
 318  312          ts_globpri,
 319  313          ia_set_process_group,
 320  314          ts_yield,
↓ open down ↓ 1076 lines elided ↑ open up ↑
1397 1391           * Do not enforce CPU caps on threads running at a kernel priority
1398 1392           */
1399 1393          if (CPUCAPS_ON()) {
1400 1394                  (void) cpucaps_charge(t, &tspp->ts_caps,
1401 1395                      CPUCAPS_CHARGE_ENFORCE);
1402 1396                  if (!(tspp->ts_flags & TSKPRI) && CPUCAPS_ENFORCE(t))
1403 1397                          return;
1404 1398          }
1405 1399  
1406 1400          /*
1407      -         * If thread got preempted in the user-land then we know
1408      -         * it isn't holding any locks.  Mark it as swappable.
1409      -         */
1410      -        ASSERT(t->t_schedflag & TS_DONT_SWAP);
1411      -        if (lwp != NULL && lwp->lwp_state == LWP_USER)
1412      -                t->t_schedflag &= ~TS_DONT_SWAP;
1413      -
1414      -        /*
1415 1401           * Check to see if we're doing "preemption control" here.  If
1416 1402           * we are, and if the user has requested that this thread not
1417 1403           * be preempted, and if preemptions haven't been put off for
1418 1404           * too long, let the preemption happen here but try to make
1419 1405           * sure the thread is rescheduled as soon as possible.  We do
1420 1406           * this by putting it on the front of the highest priority run
1421 1407           * queue in the TS class.  If the preemption has been put off
1422 1408           * for too long, clear the "nopreempt" bit and let the thread
1423 1409           * be preempted.
1424 1410           */
↓ open down ↓ 3 lines elided ↑ open up ↑
1428 1414                          if (!(tspp->ts_flags & TSKPRI)) {
1429 1415                                  /*
1430 1416                                   * If not already remembered, remember current
1431 1417                                   * priority for restoration in ts_yield().
1432 1418                                   */
1433 1419                                  if (!(tspp->ts_flags & TSRESTORE)) {
1434 1420                                          tspp->ts_scpri = t->t_pri;
1435 1421                                          tspp->ts_flags |= TSRESTORE;
1436 1422                                  }
1437 1423                                  THREAD_CHANGE_PRI(t, ts_maxumdpri);
1438      -                                t->t_schedflag |= TS_DONT_SWAP;
1439 1424                          }
1440 1425                          schedctl_set_yield(t, 1);
1441 1426                          setfrontdq(t);
1442 1427                          goto done;
1443 1428                  } else {
1444 1429                          if (tspp->ts_flags & TSRESTORE) {
1445 1430                                  THREAD_CHANGE_PRI(t, tspp->ts_scpri);
1446 1431                                  tspp->ts_flags &= ~TSRESTORE;
1447 1432                          }
1448 1433                          schedctl_set_nopreempt(t, 0);
↓ open down ↓ 106 lines elided ↑ open up ↑
1555 1540          } else if (flags & TSKPRI) {
1556 1541                  THREAD_CHANGE_PRI(curthread,
1557 1542                      ts_dptbl[tspp->ts_umdpri].ts_globpri);
1558 1543                  ASSERT(curthread->t_pri >= 0 &&
1559 1544                      curthread->t_pri <= ts_maxglobpri);
1560 1545                  tspp->ts_flags = flags & ~TSKPRI;
1561 1546  
1562 1547                  if (DISP_MUST_SURRENDER(curthread))
1563 1548                          cpu_surrender(curthread);
1564 1549          }
1565      -        t->t_stime = ddi_get_lbolt();           /* time stamp for the swapper */
1566 1550          TRACE_2(TR_FAC_DISP, TR_SLEEP,
1567 1551              "sleep:tid %p old pri %d", t, old_pri);
1568 1552  }
1569 1553  
1570      -
1571      -/*
1572      - * Return Values:
1573      - *
1574      - *      -1 if the thread is loaded or is not eligible to be swapped in.
1575      - *
1576      - *      effective priority of the specified thread based on swapout time
1577      - *              and size of process (epri >= 0 , epri <= SHRT_MAX).
1578      - */
1579      -/* ARGSUSED */
1580      -static pri_t
1581      -ts_swapin(kthread_t *t, int flags)
1582      -{
1583      -        tsproc_t        *tspp = (tsproc_t *)(t->t_cldata);
1584      -        long            epri = -1;
1585      -        proc_t          *pp = ttoproc(t);
1586      -
1587      -        ASSERT(THREAD_LOCK_HELD(t));
1588      -
1589      -        /*
1590      -         * We know that pri_t is a short.
1591      -         * Be sure not to overrun its range.
1592      -         */
1593      -        if (t->t_state == TS_RUN && (t->t_schedflag & TS_LOAD) == 0) {
1594      -                time_t swapout_time;
1595      -
1596      -                swapout_time = (ddi_get_lbolt() - t->t_stime) / hz;
1597      -                if (INHERITED(t) || (tspp->ts_flags & (TSKPRI | TSIASET)))
1598      -                        epri = (long)DISP_PRIO(t) + swapout_time;
1599      -                else {
1600      -                        /*
1601      -                         * Threads which have been out for a long time,
1602      -                         * have high user mode priority and are associated
1603      -                         * with a small address space are more deserving
1604      -                         */
1605      -                        epri = ts_dptbl[tspp->ts_umdpri].ts_globpri;
1606      -                        ASSERT(epri >= 0 && epri <= ts_maxumdpri);
1607      -                        epri += swapout_time - pp->p_swrss / nz(maxpgio)/2;
1608      -                }
1609      -                /*
1610      -                 * Scale epri so SHRT_MAX/2 represents zero priority.
1611      -                 */
1612      -                epri += SHRT_MAX/2;
1613      -                if (epri < 0)
1614      -                        epri = 0;
1615      -                else if (epri > SHRT_MAX)
1616      -                        epri = SHRT_MAX;
1617      -        }
1618      -        return ((pri_t)epri);
1619      -}
1620      -
1621      -/*
1622      - * Return Values
1623      - *      -1 if the thread isn't loaded or is not eligible to be swapped out.
1624      - *
1625      - *      effective priority of the specified thread based on if the swapper
1626      - *              is in softswap or hardswap mode.
1627      - *
1628      - *              Softswap:  Return a low effective priority for threads
1629      - *                         sleeping for more than maxslp secs.
1630      - *
1631      - *              Hardswap:  Return an effective priority such that threads
1632      - *                         which have been in memory for a while and are
1633      - *                         associated with a small address space are swapped
1634      - *                         in before others.
1635      - *
1636      - *              (epri >= 0 , epri <= SHRT_MAX).
1637      - */
1638      -time_t  ts_minrun = 2;          /* XXX - t_pri becomes 59 within 2 secs */
1639      -time_t  ts_minslp = 2;          /* min time on sleep queue for hardswap */
1640      -
1641      -static pri_t
1642      -ts_swapout(kthread_t *t, int flags)
1643      -{
1644      -        tsproc_t        *tspp = (tsproc_t *)(t->t_cldata);
1645      -        long            epri = -1;
1646      -        proc_t          *pp = ttoproc(t);
1647      -        time_t          swapin_time;
1648      -
1649      -        ASSERT(THREAD_LOCK_HELD(t));
1650      -
1651      -        if (INHERITED(t) || (tspp->ts_flags & (TSKPRI | TSIASET)) ||
1652      -            (t->t_proc_flag & TP_LWPEXIT) ||
1653      -            (t->t_state & (TS_ZOMB | TS_FREE | TS_STOPPED |
1654      -            TS_ONPROC | TS_WAIT)) ||
1655      -            !(t->t_schedflag & TS_LOAD) || !SWAP_OK(t))
1656      -                return (-1);
1657      -
1658      -        ASSERT(t->t_state & (TS_SLEEP | TS_RUN));
1659      -
1660      -        /*
1661      -         * We know that pri_t is a short.
1662      -         * Be sure not to overrun its range.
1663      -         */
1664      -        swapin_time = (ddi_get_lbolt() - t->t_stime) / hz;
1665      -        if (flags == SOFTSWAP) {
1666      -                if (t->t_state == TS_SLEEP && swapin_time > maxslp) {
1667      -                        epri = 0;
1668      -                } else {
1669      -                        return ((pri_t)epri);
1670      -                }
1671      -        } else {
1672      -                pri_t pri;
1673      -
1674      -                if ((t->t_state == TS_SLEEP && swapin_time > ts_minslp) ||
1675      -                    (t->t_state == TS_RUN && swapin_time > ts_minrun)) {
1676      -                        pri = ts_dptbl[tspp->ts_umdpri].ts_globpri;
1677      -                        ASSERT(pri >= 0 && pri <= ts_maxumdpri);
1678      -                        epri = swapin_time -
1679      -                            (rm_asrss(pp->p_as) / nz(maxpgio)/2) - (long)pri;
1680      -                } else {
1681      -                        return ((pri_t)epri);
1682      -                }
1683      -        }
1684      -
1685      -        /*
1686      -         * Scale epri so SHRT_MAX/2 represents zero priority.
1687      -         */
1688      -        epri += SHRT_MAX/2;
1689      -        if (epri < 0)
1690      -                epri = 0;
1691      -        else if (epri > SHRT_MAX)
1692      -                epri = SHRT_MAX;
1693      -
1694      -        return ((pri_t)epri);
1695      -}
1696      -
1697 1554  /*
1698 1555   * Check for time slice expiration.  If time slice has expired
1699 1556   * move thread to priority specified in tsdptbl for time slice expiration
1700 1557   * and set runrun to cause preemption.
1701 1558   */
1702 1559  static void
1703 1560  ts_tick(kthread_t *t)
1704 1561  {
1705 1562          tsproc_t *tspp = (tsproc_t *)(t->t_cldata);
1706      -        klwp_t *lwp;
1707 1563          boolean_t call_cpu_surrender = B_FALSE;
1708 1564          pri_t   oldpri = t->t_pri;
1709 1565  
1710 1566          ASSERT(MUTEX_HELD(&(ttoproc(t))->p_lock));
1711 1567  
1712 1568          thread_lock(t);
1713 1569  
1714 1570          /*
1715 1571           * Keep track of thread's project CPU usage.  Note that projects
1716 1572           * get charged even when threads are running in the kernel.
↓ open down ↓ 34 lines elided ↑ open up ↑
1751 1607                          new_pri = ts_dptbl[tspp->ts_umdpri].ts_globpri;
1752 1608                          ASSERT(new_pri >= 0 && new_pri <= ts_maxglobpri);
1753 1609                          /*
1754 1610                           * When the priority of a thread is changed,
1755 1611                           * it may be necessary to adjust its position
1756 1612                           * on a sleep queue or dispatch queue.
1757 1613                           * The function thread_change_pri accomplishes
1758 1614                           * this.
1759 1615                           */
1760 1616                          if (thread_change_pri(t, new_pri, 0)) {
1761      -                                if ((t->t_schedflag & TS_LOAD) &&
1762      -                                    (lwp = t->t_lwp) &&
1763      -                                    lwp->lwp_state == LWP_USER)
1764      -                                        t->t_schedflag &= ~TS_DONT_SWAP;
1765 1617                                  tspp->ts_timeleft =
1766 1618                                      ts_dptbl[tspp->ts_cpupri].ts_quantum;
1767 1619                          } else {
1768 1620                                  call_cpu_surrender = B_TRUE;
1769 1621                          }
1770 1622                          TRACE_2(TR_FAC_DISP, TR_TICK,
1771 1623                              "tick:tid %p old pri %d", t, oldpri);
1772 1624                  } else if (t->t_state == TS_ONPROC &&
1773 1625                      t->t_pri < t->t_disp_queue->disp_maxrunpri) {
1774 1626                          call_cpu_surrender = B_TRUE;
↓ open down ↓ 53 lines elided ↑ open up ↑
1828 1680                   */
1829 1681                  THREAD_CHANGE_PRI(t, ts_dptbl[tspp->ts_umdpri].ts_globpri);
1830 1682                  cp->cpu_dispatch_pri = DISP_PRIO(t);
1831 1683                  ASSERT(t->t_pri >= 0 && t->t_pri <= ts_maxglobpri);
1832 1684                  tspp->ts_flags &= ~TSKPRI;
1833 1685  
1834 1686                  if (DISP_MUST_SURRENDER(t))
1835 1687                          cpu_surrender(t);
1836 1688          }
1837 1689  
1838      -        /*
1839      -         * Swapout lwp if the swapper is waiting for this thread to
1840      -         * reach a safe point.
1841      -         */
1842      -        if ((t->t_schedflag & TS_SWAPENQ) && !(tspp->ts_flags & TSIASET)) {
1843      -                thread_unlock(t);
1844      -                swapout_lwp(ttolwp(t));
1845      -                thread_lock(t);
1846      -        }
1847      -
1848 1690          TRACE_2(TR_FAC_DISP, TR_TRAPRET,
1849 1691              "trapret:tid %p old pri %d", t, old_pri);
1850 1692  }
1851 1693  
1852 1694  
1853 1695  /*
1854 1696   * Update the ts_dispwait values of all time sharing threads that
1855 1697   * are currently runnable at a user mode priority and bump the priority
1856 1698   * if ts_dispwait exceeds ts_maxwait.  Called once per second via
1857 1699   * timeout which we reset here.
↓ open down ↓ 116 lines elided ↑ open up ↑
1974 1816   * for threads running in the kernel after sleeping.  The proper
1975 1817   * time quantum will be assigned by ts_trapret before the thread
1976 1818   * returns to user mode.
1977 1819   */
1978 1820  static void
1979 1821  ts_wakeup(kthread_t *t)
1980 1822  {
1981 1823          tsproc_t        *tspp = (tsproc_t *)(t->t_cldata);
1982 1824  
1983 1825          ASSERT(THREAD_LOCK_HELD(t));
1984      -
1985      -        t->t_stime = ddi_get_lbolt();           /* time stamp for the swapper */
1986 1826  
1987 1827          if (tspp->ts_flags & TSKPRI) {
1988 1828                  tspp->ts_flags &= ~TSBACKQ;
1989 1829                  if (tspp->ts_flags & TSIASET)
1990 1830                          setfrontdq(t);
1991 1831                  else
1992 1832                          setbackdq(t);
1993 1833          } else if (t->t_kpri_req) {
1994 1834                  /*
1995 1835                   * Give thread a priority boost if we were asked.
↓ open down ↓ 432 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX