#define CGROUP_FILE_NAME_MAX           (MAX_CGROUP_TYPE_NAMELEN +      \
                                         MAX_CFTYPE_NAME + 2)
+/* let's not notify more than 100 times per second */
+#define CGROUP_FILE_NOTIFY_MIN_INTV    DIV_ROUND_UP(HZ, 100)
 
 /*
  * cgroup_mutex is the master lock.  Any modification to cgroup or its
                spin_lock_irq(&cgroup_file_kn_lock);
                cfile->kn = NULL;
                spin_unlock_irq(&cgroup_file_kn_lock);
+
+               del_timer_sync(&cfile->notify_timer);
        }
 
        kernfs_remove_by_name(cgrp->kn, cgroup_file_name(cgrp, cft, name));
        return kernfs_setattr(kn, &iattr);
 }
 
+static void cgroup_file_notify_timer(struct timer_list *timer)
+{
+       cgroup_file_notify(container_of(timer, struct cgroup_file,
+                                       notify_timer));
+}
+
 static int cgroup_add_file(struct cgroup_subsys_state *css, struct cgroup *cgrp,
                           struct cftype *cft)
 {
        if (cft->file_offset) {
                struct cgroup_file *cfile = (void *)css + cft->file_offset;
 
+               timer_setup(&cfile->notify_timer, cgroup_file_notify_timer, 0);
+
                spin_lock_irq(&cgroup_file_kn_lock);
                cfile->kn = kn;
                spin_unlock_irq(&cgroup_file_kn_lock);
        unsigned long flags;
 
        spin_lock_irqsave(&cgroup_file_kn_lock, flags);
-       if (cfile->kn)
-               kernfs_notify(cfile->kn);
+       if (cfile->kn) {
+               unsigned long last = cfile->notified_at;
+               unsigned long next = last + CGROUP_FILE_NOTIFY_MIN_INTV;
+
+               if (time_in_range(jiffies, last, next)) {
+                       timer_reduce(&cfile->notify_timer, next);
+               } else {
+                       kernfs_notify(cfile->kn);
+                       cfile->notified_at = jiffies;
+               }
+       }
        spin_unlock_irqrestore(&cgroup_file_kn_lock, flags);
 }