Merge branch 'for-3.9' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 20 Feb 2013 17:16:21 +0000 (09:16 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 20 Feb 2013 17:16:21 +0000 (09:16 -0800)
Pull cgroup changes from Tejun Heo:
 "Nothing too drastic.

   - Removal of synchronize_rcu() from userland visible paths.

   - Various fixes and cleanups from Li.

   - cgroup_rightmost_descendant() added which will be used by cpuset
     changes (it will be a separate pull request)."

* 'for-3.9' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup:
  cgroup: fail if monitored file and event_control are in different cgroup
  cgroup: fix cgroup_rmdir() vs close(eventfd) race
  cpuset: fix cpuset_print_task_mems_allowed() vs rename() race
  cgroup: fix exit() vs rmdir() race
  cgroup: remove bogus comments in cgroup_diput()
  cgroup: remove synchronize_rcu() from cgroup_diput()
  cgroup: remove duplicate RCU free on struct cgroup
  sched: remove redundant NULL cgroup check in task_group_path()
  sched: split out css_online/css_offline from tg creation/destruction
  cgroup: initialize cgrp->dentry before css_alloc()
  cgroup: remove a NULL check in cgroup_exit()
  cgroup: fix bogus kernel warnings when cgroup_create() failed
  cgroup: remove synchronize_rcu() from rebind_subsystems()
  cgroup: remove synchronize_rcu() from cgroup_attach_{task|proc}()
  cgroup: use new hashtable implementation
  cgroups: fix cgroup_event_listener error handling
  cgroups: move cgroup_event_listener.c to tools/cgroup
  cgroup: implement cgroup_rightmost_descendant()
  cgroup: remove unused dummy cgroup_fork_callbacks()

1  2 
include/linux/sched.h
kernel/sched/core.c
kernel/sched/debug.c
tools/Makefile

diff --combined include/linux/sched.h
@@@ -304,6 -304,19 +304,6 @@@ static inline void lockup_detector_init
  }
  #endif
  
 -#ifdef CONFIG_DETECT_HUNG_TASK
 -extern unsigned int  sysctl_hung_task_panic;
 -extern unsigned long sysctl_hung_task_check_count;
 -extern unsigned long sysctl_hung_task_timeout_secs;
 -extern unsigned long sysctl_hung_task_warnings;
 -extern int proc_dohung_task_timeout_secs(struct ctl_table *table, int write,
 -                                       void __user *buffer,
 -                                       size_t *lenp, loff_t *ppos);
 -#else
 -/* Avoid need for ifdefs elsewhere in the code */
 -enum { sysctl_hung_task_timeout_secs = 0 };
 -#endif
 -
  /* Attach to any functions which should be ignored in wchan output. */
  #define __sched               __attribute__((__section__(".sched.text")))
  
@@@ -325,6 -338,23 +325,6 @@@ extern int mutex_spin_on_owner(struct m
  struct nsproxy;
  struct user_namespace;
  
 -/*
 - * Default maximum number of active map areas, this limits the number of vmas
 - * per mm struct. Users can overwrite this number by sysctl but there is a
 - * problem.
 - *
 - * When a program's coredump is generated as ELF format, a section is created
 - * per a vma. In ELF, the number of sections is represented in unsigned short.
 - * This means the number of sections should be smaller than 65535 at coredump.
 - * Because the kernel adds some informative sections to a image of program at
 - * generating coredump, we need some margin. The number of extra sections is
 - * 1-3 now and depends on arch. We use "5" as safe margin, here.
 - */
 -#define MAPCOUNT_ELF_CORE_MARGIN      (5)
 -#define DEFAULT_MAX_MAP_COUNT (USHRT_MAX - MAPCOUNT_ELF_CORE_MARGIN)
 -
 -extern int sysctl_max_map_count;
 -
  #include <linux/aio.h>
  
  #ifdef CONFIG_MMU
@@@ -1164,7 -1194,6 +1164,7 @@@ struct sched_entity 
        /* rq "owned" by this entity/group: */
        struct cfs_rq           *my_q;
  #endif
 +
  /*
   * Load-tracking only depends on SMP, FAIR_GROUP_SCHED dependency below may be
   * removed when useful for applications beyond shares distribution (e.g.
  struct sched_rt_entity {
        struct list_head run_list;
        unsigned long timeout;
 +      unsigned long watchdog_stamp;
        unsigned int time_slice;
  
        struct sched_rt_entity *back;
  #endif
  };
  
 -/*
 - * default timeslice is 100 msecs (used only for SCHED_RR tasks).
 - * Timeslices get refilled after they expire.
 - */
 -#define RR_TIMESLICE          (100 * HZ / 1000)
  
  struct rcu_node;
  
@@@ -1334,15 -1367,6 +1334,15 @@@ struct task_struct 
        cputime_t gtime;
  #ifndef CONFIG_VIRT_CPU_ACCOUNTING
        struct cputime prev_cputime;
 +#endif
 +#ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN
 +      seqlock_t vtime_seqlock;
 +      unsigned long long vtime_snap;
 +      enum {
 +              VTIME_SLEEPING = 0,
 +              VTIME_USER,
 +              VTIME_SYS,
 +      } vtime_snap_whence;
  #endif
        unsigned long nvcsw, nivcsw; /* context switch counts */
        struct timespec start_time;             /* monotonic time */
@@@ -1598,6 -1622,37 +1598,6 @@@ static inline void set_numabalancing_st
  }
  #endif
  
 -/*
 - * Priority of a process goes from 0..MAX_PRIO-1, valid RT
 - * priority is 0..MAX_RT_PRIO-1, and SCHED_NORMAL/SCHED_BATCH
 - * tasks are in the range MAX_RT_PRIO..MAX_PRIO-1. Priority
 - * values are inverted: lower p->prio value means higher priority.
 - *
 - * The MAX_USER_RT_PRIO value allows the actual maximum
 - * RT priority to be separate from the value exported to
 - * user-space.  This allows kernel threads to set their
 - * priority to a value higher than any user task. Note:
 - * MAX_RT_PRIO must not be smaller than MAX_USER_RT_PRIO.
 - */
 -
 -#define MAX_USER_RT_PRIO      100
 -#define MAX_RT_PRIO           MAX_USER_RT_PRIO
 -
 -#define MAX_PRIO              (MAX_RT_PRIO + 40)
 -#define DEFAULT_PRIO          (MAX_RT_PRIO + 20)
 -
 -static inline int rt_prio(int prio)
 -{
 -      if (unlikely(prio < MAX_RT_PRIO))
 -              return 1;
 -      return 0;
 -}
 -
 -static inline int rt_task(struct task_struct *p)
 -{
 -      return rt_prio(p->prio);
 -}
 -
  static inline struct pid *task_pid(struct task_struct *task)
  {
        return task->pids[PIDTYPE_PID].pid;
@@@ -1737,37 -1792,6 +1737,37 @@@ static inline void put_task_struct(stru
                __put_task_struct(t);
  }
  
 +#ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN
 +extern void task_cputime(struct task_struct *t,
 +                       cputime_t *utime, cputime_t *stime);
 +extern void task_cputime_scaled(struct task_struct *t,
 +                              cputime_t *utimescaled, cputime_t *stimescaled);
 +extern cputime_t task_gtime(struct task_struct *t);
 +#else
 +static inline void task_cputime(struct task_struct *t,
 +                              cputime_t *utime, cputime_t *stime)
 +{
 +      if (utime)
 +              *utime = t->utime;
 +      if (stime)
 +              *stime = t->stime;
 +}
 +
 +static inline void task_cputime_scaled(struct task_struct *t,
 +                                     cputime_t *utimescaled,
 +                                     cputime_t *stimescaled)
 +{
 +      if (utimescaled)
 +              *utimescaled = t->utimescaled;
 +      if (stimescaled)
 +              *stimescaled = t->stimescaled;
 +}
 +
 +static inline cputime_t task_gtime(struct task_struct *t)
 +{
 +      return t->gtime;
 +}
 +#endif
  extern void task_cputime_adjusted(struct task_struct *p, cputime_t *ut, cputime_t *st);
  extern void thread_group_cputime_adjusted(struct task_struct *p, cputime_t *ut, cputime_t *st);
  
  #define PF_MEMALLOC   0x00000800      /* Allocating memory */
  #define PF_NPROC_EXCEEDED 0x00001000  /* set_user noticed that RLIMIT_NPROC was exceeded */
  #define PF_USED_MATH  0x00002000      /* if unset the fpu must be initialized before use */
 +#define PF_USED_ASYNC 0x00004000      /* used async_schedule*(), used by module init */
  #define PF_NOFREEZE   0x00008000      /* this thread should not be frozen */
  #define PF_FROZEN     0x00010000      /* frozen for system suspend */
  #define PF_FSTRANS    0x00020000      /* inside a filesystem transaction */
@@@ -2009,7 -2032,58 +2009,7 @@@ extern void wake_up_idle_cpu(int cpu)
  static inline void wake_up_idle_cpu(int cpu) { }
  #endif
  
 -extern unsigned int sysctl_sched_latency;
 -extern unsigned int sysctl_sched_min_granularity;
 -extern unsigned int sysctl_sched_wakeup_granularity;
 -extern unsigned int sysctl_sched_child_runs_first;
 -
 -enum sched_tunable_scaling {
 -      SCHED_TUNABLESCALING_NONE,
 -      SCHED_TUNABLESCALING_LOG,
 -      SCHED_TUNABLESCALING_LINEAR,
 -      SCHED_TUNABLESCALING_END,
 -};
 -extern enum sched_tunable_scaling sysctl_sched_tunable_scaling;
 -
 -extern unsigned int sysctl_numa_balancing_scan_delay;
 -extern unsigned int sysctl_numa_balancing_scan_period_min;
 -extern unsigned int sysctl_numa_balancing_scan_period_max;
 -extern unsigned int sysctl_numa_balancing_scan_period_reset;
 -extern unsigned int sysctl_numa_balancing_scan_size;
 -extern unsigned int sysctl_numa_balancing_settle_count;
 -
 -#ifdef CONFIG_SCHED_DEBUG
 -extern unsigned int sysctl_sched_migration_cost;
 -extern unsigned int sysctl_sched_nr_migrate;
 -extern unsigned int sysctl_sched_time_avg;
 -extern unsigned int sysctl_timer_migration;
 -extern unsigned int sysctl_sched_shares_window;
 -
 -int sched_proc_update_handler(struct ctl_table *table, int write,
 -              void __user *buffer, size_t *length,
 -              loff_t *ppos);
 -#endif
 -#ifdef CONFIG_SCHED_DEBUG
 -static inline unsigned int get_sysctl_timer_migration(void)
 -{
 -      return sysctl_timer_migration;
 -}
 -#else
 -static inline unsigned int get_sysctl_timer_migration(void)
 -{
 -      return 1;
 -}
 -#endif
 -extern unsigned int sysctl_sched_rt_period;
 -extern int sysctl_sched_rt_runtime;
 -
 -int sched_rt_handler(struct ctl_table *table, int write,
 -              void __user *buffer, size_t *lenp,
 -              loff_t *ppos);
 -
  #ifdef CONFIG_SCHED_AUTOGROUP
 -extern unsigned int sysctl_sched_autogroup_enabled;
 -
  extern void sched_autogroup_create_attach(struct task_struct *p);
  extern void sched_autogroup_detach(struct task_struct *p);
  extern void sched_autogroup_fork(struct signal_struct *sig);
@@@ -2025,6 -2099,30 +2025,6 @@@ static inline void sched_autogroup_fork
  static inline void sched_autogroup_exit(struct signal_struct *sig) { }
  #endif
  
 -#ifdef CONFIG_CFS_BANDWIDTH
 -extern unsigned int sysctl_sched_cfs_bandwidth_slice;
 -#endif
 -
 -#ifdef CONFIG_RT_MUTEXES
 -extern int rt_mutex_getprio(struct task_struct *p);
 -extern void rt_mutex_setprio(struct task_struct *p, int prio);
 -extern void rt_mutex_adjust_pi(struct task_struct *p);
 -static inline bool tsk_is_pi_blocked(struct task_struct *tsk)
 -{
 -      return tsk->pi_blocked_on != NULL;
 -}
 -#else
 -static inline int rt_mutex_getprio(struct task_struct *p)
 -{
 -      return p->normal_prio;
 -}
 -# define rt_mutex_adjust_pi(p)                do { } while (0)
 -static inline bool tsk_is_pi_blocked(struct task_struct *tsk)
 -{
 -      return false;
 -}
 -#endif
 -
  extern bool yield_to(struct task_struct *p, bool preempt);
  extern void set_user_nice(struct task_struct *p, long nice);
  extern int task_prio(const struct task_struct *p);
@@@ -2615,16 -2713,7 +2615,16 @@@ static inline void thread_group_cputime
  extern void recalc_sigpending_and_wake(struct task_struct *t);
  extern void recalc_sigpending(void);
  
 -extern void signal_wake_up(struct task_struct *t, int resume_stopped);
 +extern void signal_wake_up_state(struct task_struct *t, unsigned int state);
 +
 +static inline void signal_wake_up(struct task_struct *t, bool resume)
 +{
 +      signal_wake_up_state(t, resume ? TASK_WAKEKILL : 0);
 +}
 +static inline void ptrace_signal_wake_up(struct task_struct *t, bool resume)
 +{
 +      signal_wake_up_state(t, resume ? __TASK_TRACED : 0);
 +}
  
  /*
   * Wrappers for p->thread_info->cpu access. No-op on UP.
@@@ -2654,12 -2743,17 +2654,15 @@@ static inline void set_task_cpu(struct 
  extern long sched_setaffinity(pid_t pid, const struct cpumask *new_mask);
  extern long sched_getaffinity(pid_t pid, struct cpumask *mask);
  
 -extern void normalize_rt_tasks(void);
 -
  #ifdef CONFIG_CGROUP_SCHED
  
  extern struct task_group root_task_group;
  
  extern struct task_group *sched_create_group(struct task_group *parent);
+ extern void sched_online_group(struct task_group *tg,
+                              struct task_group *parent);
  extern void sched_destroy_group(struct task_group *tg);
+ extern void sched_offline_group(struct task_group *tg);
  extern void sched_move_task(struct task_struct *tsk);
  #ifdef CONFIG_FAIR_GROUP_SCHED
  extern int sched_group_set_shares(struct task_group *tg, unsigned long shares);
diff --combined kernel/sched/core.c
@@@ -83,7 -83,7 +83,7 @@@
  #endif
  
  #include "sched.h"
 -#include "../workqueue_sched.h"
 +#include "../workqueue_internal.h"
  #include "../smpboot.h"
  
  #define CREATE_TRACE_POINTS
@@@ -1523,8 -1523,7 +1523,8 @@@ out
   */
  int wake_up_process(struct task_struct *p)
  {
 -      return try_to_wake_up(p, TASK_ALL, 0);
 +      WARN_ON(task_is_stopped_or_traced(p));
 +      return try_to_wake_up(p, TASK_NORMAL, 0);
  }
  EXPORT_SYMBOL(wake_up_process);
  
@@@ -4371,7 -4370,7 +4371,7 @@@ bool __sched yield_to(struct task_struc
        struct task_struct *curr = current;
        struct rq *rq, *p_rq;
        unsigned long flags;
 -      bool yielded = 0;
 +      int yielded = 0;
  
        local_irq_save(flags);
        rq = this_rq();
@@@ -4667,7 -4666,6 +4667,7 @@@ void __cpuinit init_idle(struct task_st
         */
        idle->sched_class = &idle_sched_class;
        ftrace_graph_init_idle_task(idle, cpu);
 +      vtime_init_idle(idle);
  #if defined(CONFIG_SMP)
        sprintf(idle->comm, "%s/%d", INIT_TASK_COMM, cpu);
  #endif
@@@ -7161,7 -7159,6 +7161,6 @@@ static void free_sched_group(struct tas
  struct task_group *sched_create_group(struct task_group *parent)
  {
        struct task_group *tg;
-       unsigned long flags;
  
        tg = kzalloc(sizeof(*tg), GFP_KERNEL);
        if (!tg)
        if (!alloc_rt_sched_group(tg, parent))
                goto err;
  
+       return tg;
+ err:
+       free_sched_group(tg);
+       return ERR_PTR(-ENOMEM);
+ }
+ void sched_online_group(struct task_group *tg, struct task_group *parent)
+ {
+       unsigned long flags;
        spin_lock_irqsave(&task_group_lock, flags);
        list_add_rcu(&tg->list, &task_groups);
  
        INIT_LIST_HEAD(&tg->children);
        list_add_rcu(&tg->siblings, &parent->children);
        spin_unlock_irqrestore(&task_group_lock, flags);
-       return tg;
- err:
-       free_sched_group(tg);
-       return ERR_PTR(-ENOMEM);
  }
  
  /* rcu callback to free various structures associated with a task group */
@@@ -7199,6 -7201,12 +7203,12 @@@ static void free_sched_group_rcu(struc
  
  /* Destroy runqueue etc associated with a task group */
  void sched_destroy_group(struct task_group *tg)
+ {
+       /* wait for possible concurrent references to cfs_rqs complete */
+       call_rcu(&tg->rcu, free_sched_group_rcu);
+ }
+ void sched_offline_group(struct task_group *tg)
  {
        unsigned long flags;
        int i;
        list_del_rcu(&tg->list);
        list_del_rcu(&tg->siblings);
        spin_unlock_irqrestore(&task_group_lock, flags);
-       /* wait for possible concurrent references to cfs_rqs complete */
-       call_rcu(&tg->rcu, free_sched_group_rcu);
  }
  
  /* change task's runqueue when it moves between groups.
@@@ -7509,25 -7514,6 +7516,25 @@@ static int sched_rt_global_constraints(
  }
  #endif /* CONFIG_RT_GROUP_SCHED */
  
 +int sched_rr_handler(struct ctl_table *table, int write,
 +              void __user *buffer, size_t *lenp,
 +              loff_t *ppos)
 +{
 +      int ret;
 +      static DEFINE_MUTEX(mutex);
 +
 +      mutex_lock(&mutex);
 +      ret = proc_dointvec(table, write, buffer, lenp, ppos);
 +      /* make sure that internally we keep jiffies */
 +      /* also, writing zero resets timeslice to default */
 +      if (!ret && write) {
 +              sched_rr_timeslice = sched_rr_timeslice <= 0 ?
 +                      RR_TIMESLICE : msecs_to_jiffies(sched_rr_timeslice);
 +      }
 +      mutex_unlock(&mutex);
 +      return ret;
 +}
 +
  int sched_rt_handler(struct ctl_table *table, int write,
                void __user *buffer, size_t *lenp,
                loff_t *ppos)
@@@ -7584,6 -7570,19 +7591,19 @@@ static struct cgroup_subsys_state *cpu_
        return &tg->css;
  }
  
+ static int cpu_cgroup_css_online(struct cgroup *cgrp)
+ {
+       struct task_group *tg = cgroup_tg(cgrp);
+       struct task_group *parent;
+       if (!cgrp->parent)
+               return 0;
+       parent = cgroup_tg(cgrp->parent);
+       sched_online_group(tg, parent);
+       return 0;
+ }
  static void cpu_cgroup_css_free(struct cgroup *cgrp)
  {
        struct task_group *tg = cgroup_tg(cgrp);
        sched_destroy_group(tg);
  }
  
+ static void cpu_cgroup_css_offline(struct cgroup *cgrp)
+ {
+       struct task_group *tg = cgroup_tg(cgrp);
+       sched_offline_group(tg);
+ }
  static int cpu_cgroup_can_attach(struct cgroup *cgrp,
                                 struct cgroup_taskset *tset)
  {
@@@ -7946,6 -7952,8 +7973,8 @@@ struct cgroup_subsys cpu_cgroup_subsys 
        .name           = "cpu",
        .css_alloc      = cpu_cgroup_css_alloc,
        .css_free       = cpu_cgroup_css_free,
+       .css_online     = cpu_cgroup_css_online,
+       .css_offline    = cpu_cgroup_css_offline,
        .can_attach     = cpu_cgroup_can_attach,
        .attach         = cpu_cgroup_attach,
        .exit           = cpu_cgroup_exit,
diff --combined kernel/sched/debug.c
@@@ -110,13 -110,6 +110,6 @@@ static char *task_group_path(struct tas
        if (autogroup_path(tg, group_path, PATH_MAX))
                return group_path;
  
-       /*
-        * May be NULL if the underlying cgroup isn't fully-created yet
-        */
-       if (!tg->css.cgroup) {
-               group_path[0] = '\0';
-               return group_path;
-       }
        cgroup_path(tg->css.cgroup, group_path, PATH_MAX);
        return group_path;
  }
@@@ -222,8 -215,8 +215,8 @@@ void print_cfs_rq(struct seq_file *m, i
                        cfs_rq->runnable_load_avg);
        SEQ_printf(m, "  .%-30s: %lld\n", "blocked_load_avg",
                        cfs_rq->blocked_load_avg);
 -      SEQ_printf(m, "  .%-30s: %ld\n", "tg_load_avg",
 -                      atomic64_read(&cfs_rq->tg->load_avg));
 +      SEQ_printf(m, "  .%-30s: %lld\n", "tg_load_avg",
 +                      (unsigned long long)atomic64_read(&cfs_rq->tg->load_avg));
        SEQ_printf(m, "  .%-30s: %lld\n", "tg_load_contrib",
                        cfs_rq->tg_load_contrib);
        SEQ_printf(m, "  .%-30s: %d\n", "tg_runnable_contrib",
diff --combined tools/Makefile
@@@ -3,6 -3,7 +3,7 @@@ include scripts/Makefile.includ
  help:
        @echo 'Possible targets:'
        @echo ''
+       @echo '  cgroup     - cgroup tools'
        @echo '  cpupower   - a tool for all things x86 CPU power'
        @echo '  firewire   - the userspace part of nosy, an IEEE-1394 traffic sniffer'
        @echo '  lguest     - a minimal 32-bit x86 hypervisor'
@@@ -15,7 -16,7 +16,7 @@@
        @echo '  x86_energy_perf_policy - Intel energy policy tool'
        @echo ''
        @echo 'You can do:'
 -      @echo ' $$ make -C tools/<tool>_install'
 +      @echo ' $$ make -C tools/ <tool>_install'
        @echo ''
        @echo '  from the kernel command line to build and install one of'
        @echo '  the tools above'
@@@ -33,7 -34,7 +34,7 @@@
  cpupower: FORCE
        $(call descend,power/$@)
  
- firewire lguest perf usb virtio vm: FORCE
cgroup firewire lguest perf usb virtio vm: FORCE
        $(call descend,$@)
  
  selftests: FORCE
@@@ -45,7 -46,7 +46,7 @@@ turbostat x86_energy_perf_policy: FORC
  cpupower_install:
        $(call descend,power/$(@:_install=),install)
  
- firewire_install lguest_install perf_install usb_install virtio_install vm_install:
cgroup_install firewire_install lguest_install perf_install usb_install virtio_install vm_install:
        $(call descend,$(@:_install=),install)
  
  selftests_install:
  turbostat_install x86_energy_perf_policy_install:
        $(call descend,power/x86/$(@:_install=),install)
  
- install: cpupower_install firewire_install lguest_install perf_install \
-               selftests_install turbostat_install usb_install virtio_install \
-               vm_install x86_energy_perf_policy_install
+ install: cgroup_install cpupower_install firewire_install lguest_install \
+               perf_install selftests_install turbostat_install usb_install \
+               virtio_install vm_install x86_energy_perf_policy_install
  
  cpupower_clean:
        $(call descend,power/cpupower,clean)
  
- firewire_clean lguest_clean perf_clean usb_clean virtio_clean vm_clean:
cgroup_clean firewire_clean lguest_clean perf_clean usb_clean virtio_clean vm_clean:
        $(call descend,$(@:_clean=),clean)
  
  selftests_clean:
@@@ -70,8 -71,8 +71,8 @@@
  turbostat_clean x86_energy_perf_policy_clean:
        $(call descend,power/x86/$(@:_clean=),clean)
  
- clean: cpupower_clean firewire_clean lguest_clean perf_clean selftests_clean \
-               turbostat_clean usb_clean virtio_clean vm_clean \
-               x86_energy_perf_policy_clean
+ clean: cgroup_clean cpupower_clean firewire_clean lguest_clean perf_clean \
+               selftests_clean turbostat_clean usb_clean virtio_clean \
+               vm_clean x86_energy_perf_policy_clean
  
  .PHONY: FORCE