Merge branch 'v28-timers-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
Linus Torvalds [Mon, 20 Oct 2008 20:19:56 +0000 (13:19 -0700)]
* 'v28-timers-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: (36 commits)
  fix documentation of sysrq-q really
  Fix documentation of sysrq-q
  timer_list: add base address to clock base
  timer_list: print cpu number of clockevents device
  timer_list: print real timer address
  NOHZ: restart tick device from irq_enter()
  NOHZ: split tick_nohz_restart_sched_tick()
  NOHZ: unify the nohz function calls in irq_enter()
  timers: fix itimer/many thread hang, fix
  timers: fix itimer/many thread hang, v3
  ntp: improve adjtimex frequency rounding
  timekeeping: fix rounding problem during clock update
  ntp: let update_persistent_clock() sleep
  hrtimer: reorder struct hrtimer to save 8 bytes on 64bit builds
  posix-timers: lock_timer: make it readable
  posix-timers: lock_timer: kill the bogus ->it_id check
  posix-timers: kill ->it_sigev_signo and ->it_sigev_value
  posix-timers: sys_timer_create: cleanup the error handling
  posix-timers: move the initialization of timer->sigq from send to create path
  posix-timers: sys_timer_create: simplify and s/tasklist/rcu/
  ...

Fix trivial conflicts due to sysrq-q description clahes in
Documentation/sysrq.txt and drivers/char/sysrq.c

1  2 
Documentation/sysrq.txt
fs/binfmt_elf.c
include/linux/sched.h

diff --combined Documentation/sysrq.txt
@@@ -95,8 -95,8 +95,9 @@@ On all -  write a character to /proc/sy
  
  'p'     - Will dump the current registers and flags to your console.
  
- 'q'     - Will dump a list of all running hrtimers.
-         WARNING: Does not cover any other timers
 -'q'     - Will dump per CPU lists of all armed hrtimers (not timer_list timers)
 -        and detailed information about all clockevent devices.
++'q'     - Will dump per CPU lists of all armed hrtimers (but NOT regular
++          timer_list timers) and detailed information about all
++          clockevent devices.
  
  'r'     - Turns off keyboard raw mode and sets it to XLATE.
  
diff --combined fs/binfmt_elf.c
@@@ -1156,24 -1156,16 +1156,24 @@@ static int dump_seek(struct file *file
  static unsigned long vma_dump_size(struct vm_area_struct *vma,
                                   unsigned long mm_flags)
  {
 +#define FILTER(type)  (mm_flags & (1UL << MMF_DUMP_##type))
 +
        /* The vma can be set up to tell us the answer directly.  */
        if (vma->vm_flags & VM_ALWAYSDUMP)
                goto whole;
  
 +      /* Hugetlb memory check */
 +      if (vma->vm_flags & VM_HUGETLB) {
 +              if ((vma->vm_flags & VM_SHARED) && FILTER(HUGETLB_SHARED))
 +                      goto whole;
 +              if (!(vma->vm_flags & VM_SHARED) && FILTER(HUGETLB_PRIVATE))
 +                      goto whole;
 +      }
 +
        /* Do not dump I/O mapped devices or special mappings */
        if (vma->vm_flags & (VM_IO | VM_RESERVED))
                return 0;
  
 -#define FILTER(type)  (mm_flags & (1UL << MMF_DUMP_##type))
 -
        /* By default, dump shared memory if mapped from an anonymous file. */
        if (vma->vm_flags & VM_SHARED) {
                if (vma->vm_file->f_path.dentry->d_inode->i_nlink == 0 ?
@@@ -1341,20 -1333,15 +1341,15 @@@ static void fill_prstatus(struct elf_pr
        prstatus->pr_pgrp = task_pgrp_vnr(p);
        prstatus->pr_sid = task_session_vnr(p);
        if (thread_group_leader(p)) {
+               struct task_cputime cputime;
                /*
-                * This is the record for the group leader.  Add in the
-                * cumulative times of previous dead threads.  This total
-                * won't include the time of each live thread whose state
-                * is included in the core dump.  The final total reported
-                * to our parent process when it calls wait4 will include
-                * those sums as well as the little bit more time it takes
-                * this and each other thread to finish dying after the
-                * core dump synchronization phase.
+                * This is the record for the group leader.  It shows the
+                * group-wide total, not its individual thread total.
                 */
-               cputime_to_timeval(cputime_add(p->utime, p->signal->utime),
-                                  &prstatus->pr_utime);
-               cputime_to_timeval(cputime_add(p->stime, p->signal->stime),
-                                  &prstatus->pr_stime);
+               thread_group_cputime(p, &cputime);
+               cputime_to_timeval(cputime.utime, &prstatus->pr_utime);
+               cputime_to_timeval(cputime.stime, &prstatus->pr_stime);
        } else {
                cputime_to_timeval(p->utime, &prstatus->pr_utime);
                cputime_to_timeval(p->stime, &prstatus->pr_stime);
diff --combined include/linux/sched.h
@@@ -403,21 -403,12 +403,21 @@@ extern int get_dumpable(struct mm_struc
  #define MMF_DUMP_MAPPED_PRIVATE       4
  #define MMF_DUMP_MAPPED_SHARED        5
  #define MMF_DUMP_ELF_HEADERS  6
 +#define MMF_DUMP_HUGETLB_PRIVATE 7
 +#define MMF_DUMP_HUGETLB_SHARED  8
  #define MMF_DUMP_FILTER_SHIFT MMF_DUMPABLE_BITS
 -#define MMF_DUMP_FILTER_BITS  5
 +#define MMF_DUMP_FILTER_BITS  7
  #define MMF_DUMP_FILTER_MASK \
        (((1 << MMF_DUMP_FILTER_BITS) - 1) << MMF_DUMP_FILTER_SHIFT)
  #define MMF_DUMP_FILTER_DEFAULT \
 -      ((1 << MMF_DUMP_ANON_PRIVATE) | (1 << MMF_DUMP_ANON_SHARED))
 +      ((1 << MMF_DUMP_ANON_PRIVATE) | (1 << MMF_DUMP_ANON_SHARED) |\
 +       (1 << MMF_DUMP_HUGETLB_PRIVATE) | MMF_DUMP_MASK_DEFAULT_ELF)
 +
 +#ifdef CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS
 +# define MMF_DUMP_MASK_DEFAULT_ELF    (1 << MMF_DUMP_ELF_HEADERS)
 +#else
 +# define MMF_DUMP_MASK_DEFAULT_ELF    0
 +#endif
  
  struct sighand_struct {
        atomic_t                count;
@@@ -434,6 -425,39 +434,39 @@@ struct pacct_struct 
        unsigned long           ac_minflt, ac_majflt;
  };
  
+ /**
+  * struct task_cputime - collected CPU time counts
+  * @utime:            time spent in user mode, in &cputime_t units
+  * @stime:            time spent in kernel mode, in &cputime_t units
+  * @sum_exec_runtime: total time spent on the CPU, in nanoseconds
+  *
+  * This structure groups together three kinds of CPU time that are
+  * tracked for threads and thread groups.  Most things considering
+  * CPU time want to group these counts together and treat all three
+  * of them in parallel.
+  */
+ struct task_cputime {
+       cputime_t utime;
+       cputime_t stime;
+       unsigned long long sum_exec_runtime;
+ };
+ /* Alternate field names when used to cache expirations. */
+ #define prof_exp      stime
+ #define virt_exp      utime
+ #define sched_exp     sum_exec_runtime
+ /**
+  * struct thread_group_cputime - thread group interval timer counts
+  * @totals:           thread group interval timers; substructure for
+  *                    uniprocessor kernel, per-cpu for SMP kernel.
+  *
+  * This structure contains the version of task_cputime, above, that is
+  * used for thread group CPU clock calculations.
+  */
+ struct thread_group_cputime {
+       struct task_cputime *totals;
+ };
  /*
   * NOTE! "signal_struct" does not have it's own
   * locking, because a shared signal_struct always
@@@ -479,6 -503,17 +512,17 @@@ struct signal_struct 
        cputime_t it_prof_expires, it_virt_expires;
        cputime_t it_prof_incr, it_virt_incr;
  
+       /*
+        * Thread group totals for process CPU clocks.
+        * See thread_group_cputime(), et al, for details.
+        */
+       struct thread_group_cputime cputime;
+       /* Earliest-expiration cache. */
+       struct task_cputime cputime_expires;
+       struct list_head cpu_timers[3];
        /* job control IDs */
  
        /*
         * Live threads maintain their own counters and add to these
         * in __exit_signal, except for the group leader.
         */
-       cputime_t utime, stime, cutime, cstime;
+       cputime_t cutime, cstime;
        cputime_t gtime;
        cputime_t cgtime;
        unsigned long nvcsw, nivcsw, cnvcsw, cnivcsw;
        struct task_io_accounting ioac;
  
        /*
-        * Cumulative ns of scheduled CPU time for dead threads in the
-        * group, not including a zombie group leader.  (This only differs
-        * from jiffies_to_ns(utime + stime) if sched_clock uses something
-        * other than jiffies.)
-        */
-       unsigned long long sum_sched_runtime;
-       /*
         * We don't bother to synchronize most readers of this at all,
         * because there is no reader checking a limit that actually needs
         * to get both rlim_cur and rlim_max atomically, and either one
         */
        struct rlimit rlim[RLIM_NLIMITS];
  
-       struct list_head cpu_timers[3];
        /* keep the process-shared keyrings here so that they do the right
         * thing in threads created with CLONE_THREAD */
  #ifdef CONFIG_KEYS
@@@ -1146,8 -1171,7 +1180,7 @@@ struct task_struct 
  /* mm fault and swap info: this can arguably be seen as either mm-specific or thread-specific */
        unsigned long min_flt, maj_flt;
  
-       cputime_t it_prof_expires, it_virt_expires;
-       unsigned long long it_sched_expires;
+       struct task_cputime cputime_expires;
        struct list_head cpu_timers[3];
  
  /* process credentials */
@@@ -1597,6 -1621,7 +1630,7 @@@ extern unsigned long long cpu_clock(in
  
  extern unsigned long long
  task_sched_runtime(struct task_struct *task);
+ extern unsigned long long thread_group_sched_runtime(struct task_struct *task);
  
  /* sched_exec is called by processes performing an exec */
  #ifdef CONFIG_SMP
@@@ -2094,6 -2119,30 +2128,30 @@@ static inline int spin_needbreak(spinlo
  }
  
  /*
+  * Thread group CPU time accounting.
+  */
+ extern int thread_group_cputime_alloc(struct task_struct *);
+ extern void thread_group_cputime(struct task_struct *, struct task_cputime *);
+ static inline void thread_group_cputime_init(struct signal_struct *sig)
+ {
+       sig->cputime.totals = NULL;
+ }
+ static inline int thread_group_cputime_clone_thread(struct task_struct *curr)
+ {
+       if (curr->signal->cputime.totals)
+               return 0;
+       return thread_group_cputime_alloc(curr);
+ }
+ static inline void thread_group_cputime_free(struct signal_struct *sig)
+ {
+       free_percpu(sig->cputime.totals);
+ }
+ /*
   * Reevaluate whether the task has signals pending delivery.
   * Wake the task if so.
   * This is required every time the blocked sigset_t changes.