diff options
Diffstat (limited to 'kernel/timer.c')
-rw-r--r-- | kernel/timer.c | 161 |
1 files changed, 11 insertions, 150 deletions
diff --git a/kernel/timer.c b/kernel/timer.c index dbf7a78a1ef1..15ffdb3f1948 100644 --- a/kernel/timer.c +++ b/kernel/timer.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * linux/kernel/timer.c | 2 | * linux/kernel/timer.c |
3 | * | 3 | * |
4 | * Kernel internal timers, basic process system calls | 4 | * Kernel internal timers |
5 | * | 5 | * |
6 | * Copyright (C) 1991, 1992 Linus Torvalds | 6 | * Copyright (C) 1991, 1992 Linus Torvalds |
7 | * | 7 | * |
@@ -41,6 +41,7 @@ | |||
41 | #include <linux/sched.h> | 41 | #include <linux/sched.h> |
42 | #include <linux/sched/sysctl.h> | 42 | #include <linux/sched/sysctl.h> |
43 | #include <linux/slab.h> | 43 | #include <linux/slab.h> |
44 | #include <linux/compat.h> | ||
44 | 45 | ||
45 | #include <asm/uaccess.h> | 46 | #include <asm/uaccess.h> |
46 | #include <asm/unistd.h> | 47 | #include <asm/unistd.h> |
@@ -738,7 +739,7 @@ __mod_timer(struct timer_list *timer, unsigned long expires, | |||
738 | 739 | ||
739 | cpu = smp_processor_id(); | 740 | cpu = smp_processor_id(); |
740 | 741 | ||
741 | #if defined(CONFIG_NO_HZ) && defined(CONFIG_SMP) | 742 | #if defined(CONFIG_NO_HZ_COMMON) && defined(CONFIG_SMP) |
742 | if (!pinned && get_sysctl_timer_migration() && idle_cpu(cpu)) | 743 | if (!pinned && get_sysctl_timer_migration() && idle_cpu(cpu)) |
743 | cpu = get_nohz_timer_target(); | 744 | cpu = get_nohz_timer_target(); |
744 | #endif | 745 | #endif |
@@ -930,14 +931,14 @@ void add_timer_on(struct timer_list *timer, int cpu) | |||
930 | debug_activate(timer, timer->expires); | 931 | debug_activate(timer, timer->expires); |
931 | internal_add_timer(base, timer); | 932 | internal_add_timer(base, timer); |
932 | /* | 933 | /* |
933 | * Check whether the other CPU is idle and needs to be | 934 | * Check whether the other CPU is in dynticks mode and needs |
934 | * triggered to reevaluate the timer wheel when nohz is | 935 | * to be triggered to reevaluate the timer wheel. |
935 | * active. We are protected against the other CPU fiddling | 936 | * We are protected against the other CPU fiddling |
936 | * with the timer by holding the timer base lock. This also | 937 | * with the timer by holding the timer base lock. This also |
937 | * makes sure that a CPU on the way to idle can not evaluate | 938 | * makes sure that a CPU on the way to stop its tick can not |
938 | * the timer wheel. | 939 | * evaluate the timer wheel. |
939 | */ | 940 | */ |
940 | wake_up_idle_cpu(cpu); | 941 | wake_up_nohz_cpu(cpu); |
941 | spin_unlock_irqrestore(&base->lock, flags); | 942 | spin_unlock_irqrestore(&base->lock, flags); |
942 | } | 943 | } |
943 | EXPORT_SYMBOL_GPL(add_timer_on); | 944 | EXPORT_SYMBOL_GPL(add_timer_on); |
@@ -1188,7 +1189,7 @@ static inline void __run_timers(struct tvec_base *base) | |||
1188 | spin_unlock_irq(&base->lock); | 1189 | spin_unlock_irq(&base->lock); |
1189 | } | 1190 | } |
1190 | 1191 | ||
1191 | #ifdef CONFIG_NO_HZ | 1192 | #ifdef CONFIG_NO_HZ_COMMON |
1192 | /* | 1193 | /* |
1193 | * Find out when the next timer event is due to happen. This | 1194 | * Find out when the next timer event is due to happen. This |
1194 | * is used on S/390 to stop all activity when a CPU is idle. | 1195 | * is used on S/390 to stop all activity when a CPU is idle. |
@@ -1395,61 +1396,6 @@ SYSCALL_DEFINE1(alarm, unsigned int, seconds) | |||
1395 | 1396 | ||
1396 | #endif | 1397 | #endif |
1397 | 1398 | ||
1398 | /** | ||
1399 | * sys_getpid - return the thread group id of the current process | ||
1400 | * | ||
1401 | * Note, despite the name, this returns the tgid not the pid. The tgid and | ||
1402 | * the pid are identical unless CLONE_THREAD was specified on clone() in | ||
1403 | * which case the tgid is the same in all threads of the same group. | ||
1404 | * | ||
1405 | * This is SMP safe as current->tgid does not change. | ||
1406 | */ | ||
1407 | SYSCALL_DEFINE0(getpid) | ||
1408 | { | ||
1409 | return task_tgid_vnr(current); | ||
1410 | } | ||
1411 | |||
1412 | /* | ||
1413 | * Accessing ->real_parent is not SMP-safe, it could | ||
1414 | * change from under us. However, we can use a stale | ||
1415 | * value of ->real_parent under rcu_read_lock(), see | ||
1416 | * release_task()->call_rcu(delayed_put_task_struct). | ||
1417 | */ | ||
1418 | SYSCALL_DEFINE0(getppid) | ||
1419 | { | ||
1420 | int pid; | ||
1421 | |||
1422 | rcu_read_lock(); | ||
1423 | pid = task_tgid_vnr(rcu_dereference(current->real_parent)); | ||
1424 | rcu_read_unlock(); | ||
1425 | |||
1426 | return pid; | ||
1427 | } | ||
1428 | |||
1429 | SYSCALL_DEFINE0(getuid) | ||
1430 | { | ||
1431 | /* Only we change this so SMP safe */ | ||
1432 | return from_kuid_munged(current_user_ns(), current_uid()); | ||
1433 | } | ||
1434 | |||
1435 | SYSCALL_DEFINE0(geteuid) | ||
1436 | { | ||
1437 | /* Only we change this so SMP safe */ | ||
1438 | return from_kuid_munged(current_user_ns(), current_euid()); | ||
1439 | } | ||
1440 | |||
1441 | SYSCALL_DEFINE0(getgid) | ||
1442 | { | ||
1443 | /* Only we change this so SMP safe */ | ||
1444 | return from_kgid_munged(current_user_ns(), current_gid()); | ||
1445 | } | ||
1446 | |||
1447 | SYSCALL_DEFINE0(getegid) | ||
1448 | { | ||
1449 | /* Only we change this so SMP safe */ | ||
1450 | return from_kgid_munged(current_user_ns(), current_egid()); | ||
1451 | } | ||
1452 | |||
1453 | static void process_timeout(unsigned long __data) | 1399 | static void process_timeout(unsigned long __data) |
1454 | { | 1400 | { |
1455 | wake_up_process((struct task_struct *)__data); | 1401 | wake_up_process((struct task_struct *)__data); |
@@ -1557,91 +1503,6 @@ signed long __sched schedule_timeout_uninterruptible(signed long timeout) | |||
1557 | } | 1503 | } |
1558 | EXPORT_SYMBOL(schedule_timeout_uninterruptible); | 1504 | EXPORT_SYMBOL(schedule_timeout_uninterruptible); |
1559 | 1505 | ||
1560 | /* Thread ID - the internal kernel "pid" */ | ||
1561 | SYSCALL_DEFINE0(gettid) | ||
1562 | { | ||
1563 | return task_pid_vnr(current); | ||
1564 | } | ||
1565 | |||
1566 | /** | ||
1567 | * do_sysinfo - fill in sysinfo struct | ||
1568 | * @info: pointer to buffer to fill | ||
1569 | */ | ||
1570 | int do_sysinfo(struct sysinfo *info) | ||
1571 | { | ||
1572 | unsigned long mem_total, sav_total; | ||
1573 | unsigned int mem_unit, bitcount; | ||
1574 | struct timespec tp; | ||
1575 | |||
1576 | memset(info, 0, sizeof(struct sysinfo)); | ||
1577 | |||
1578 | ktime_get_ts(&tp); | ||
1579 | monotonic_to_bootbased(&tp); | ||
1580 | info->uptime = tp.tv_sec + (tp.tv_nsec ? 1 : 0); | ||
1581 | |||
1582 | get_avenrun(info->loads, 0, SI_LOAD_SHIFT - FSHIFT); | ||
1583 | |||
1584 | info->procs = nr_threads; | ||
1585 | |||
1586 | si_meminfo(info); | ||
1587 | si_swapinfo(info); | ||
1588 | |||
1589 | /* | ||
1590 | * If the sum of all the available memory (i.e. ram + swap) | ||
1591 | * is less than can be stored in a 32 bit unsigned long then | ||
1592 | * we can be binary compatible with 2.2.x kernels. If not, | ||
1593 | * well, in that case 2.2.x was broken anyways... | ||
1594 | * | ||
1595 | * -Erik Andersen <andersee@debian.org> | ||
1596 | */ | ||
1597 | |||
1598 | mem_total = info->totalram + info->totalswap; | ||
1599 | if (mem_total < info->totalram || mem_total < info->totalswap) | ||
1600 | goto out; | ||
1601 | bitcount = 0; | ||
1602 | mem_unit = info->mem_unit; | ||
1603 | while (mem_unit > 1) { | ||
1604 | bitcount++; | ||
1605 | mem_unit >>= 1; | ||
1606 | sav_total = mem_total; | ||
1607 | mem_total <<= 1; | ||
1608 | if (mem_total < sav_total) | ||
1609 | goto out; | ||
1610 | } | ||
1611 | |||
1612 | /* | ||
1613 | * If mem_total did not overflow, multiply all memory values by | ||
1614 | * info->mem_unit and set it to 1. This leaves things compatible | ||
1615 | * with 2.2.x, and also retains compatibility with earlier 2.4.x | ||
1616 | * kernels... | ||
1617 | */ | ||
1618 | |||
1619 | info->mem_unit = 1; | ||
1620 | info->totalram <<= bitcount; | ||
1621 | info->freeram <<= bitcount; | ||
1622 | info->sharedram <<= bitcount; | ||
1623 | info->bufferram <<= bitcount; | ||
1624 | info->totalswap <<= bitcount; | ||
1625 | info->freeswap <<= bitcount; | ||
1626 | info->totalhigh <<= bitcount; | ||
1627 | info->freehigh <<= bitcount; | ||
1628 | |||
1629 | out: | ||
1630 | return 0; | ||
1631 | } | ||
1632 | |||
1633 | SYSCALL_DEFINE1(sysinfo, struct sysinfo __user *, info) | ||
1634 | { | ||
1635 | struct sysinfo val; | ||
1636 | |||
1637 | do_sysinfo(&val); | ||
1638 | |||
1639 | if (copy_to_user(info, &val, sizeof(struct sysinfo))) | ||
1640 | return -EFAULT; | ||
1641 | |||
1642 | return 0; | ||
1643 | } | ||
1644 | |||
1645 | static int __cpuinit init_timers_cpu(int cpu) | 1506 | static int __cpuinit init_timers_cpu(int cpu) |
1646 | { | 1507 | { |
1647 | int j; | 1508 | int j; |
@@ -1678,12 +1539,12 @@ static int __cpuinit init_timers_cpu(int cpu) | |||
1678 | boot_done = 1; | 1539 | boot_done = 1; |
1679 | base = &boot_tvec_bases; | 1540 | base = &boot_tvec_bases; |
1680 | } | 1541 | } |
1542 | spin_lock_init(&base->lock); | ||
1681 | tvec_base_done[cpu] = 1; | 1543 | tvec_base_done[cpu] = 1; |
1682 | } else { | 1544 | } else { |
1683 | base = per_cpu(tvec_bases, cpu); | 1545 | base = per_cpu(tvec_bases, cpu); |
1684 | } | 1546 | } |
1685 | 1547 | ||
1686 | spin_lock_init(&base->lock); | ||
1687 | 1548 | ||
1688 | for (j = 0; j < TVN_SIZE; j++) { | 1549 | for (j = 0; j < TVN_SIZE; j++) { |
1689 | INIT_LIST_HEAD(base->tv5.vec + j); | 1550 | INIT_LIST_HEAD(base->tv5.vec + j); |