summaryrefslogtreecommitdiffstats
path: root/kernel/cgroup
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2018-04-26 17:29:04 -0400
committerTejun Heo <tj@kernel.org>2018-04-26 17:29:04 -0400
commitb12e35832805bf120819b83d8fdb6e4d227a5ddb (patch)
tree87b6b3697fded167ad801db2f8fd654815ec8016 /kernel/cgroup
parent5faaf05f2976fd9ec0ecd582bcfb3a41cde4c65e (diff)
cgroup: Limit event generation frequency
".events" files generate file modified event to notify userland of possible new events. Some of the events can be quite bursty (e.g. memory high event) and generating notification each time is costly and pointless. This patch implements a event rate limit mechanism. If a new notification is requested before 10ms has passed since the previous notification, the new notification is delayed till then. As this only delays from the second notification on in a given close cluster of notifications, userland reactions to notifications shouldn't be delayed at all in most cases while avoiding notification storms. Signed-off-by: Tejun Heo <tj@kernel.org>
Diffstat (limited to 'kernel/cgroup')
-rw-r--r--kernel/cgroup/cgroup.c25
1 files changed, 23 insertions, 2 deletions
diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c
index 25309c868728..fdb7a582f8fc 100644
--- a/kernel/cgroup/cgroup.c
+++ b/kernel/cgroup/cgroup.c
@@ -61,6 +61,8 @@
61 61
62#define CGROUP_FILE_NAME_MAX (MAX_CGROUP_TYPE_NAMELEN + \ 62#define CGROUP_FILE_NAME_MAX (MAX_CGROUP_TYPE_NAMELEN + \
63 MAX_CFTYPE_NAME + 2) 63 MAX_CFTYPE_NAME + 2)
64/* let's not notify more than 100 times per second */
65#define CGROUP_FILE_NOTIFY_MIN_INTV DIV_ROUND_UP(HZ, 100)
64 66
65/* 67/*
66 * cgroup_mutex is the master lock. Any modification to cgroup or its 68 * cgroup_mutex is the master lock. Any modification to cgroup or its
@@ -1554,6 +1556,8 @@ static void cgroup_rm_file(struct cgroup *cgrp, const struct cftype *cft)
1554 spin_lock_irq(&cgroup_file_kn_lock); 1556 spin_lock_irq(&cgroup_file_kn_lock);
1555 cfile->kn = NULL; 1557 cfile->kn = NULL;
1556 spin_unlock_irq(&cgroup_file_kn_lock); 1558 spin_unlock_irq(&cgroup_file_kn_lock);
1559
1560 del_timer_sync(&cfile->notify_timer);
1557 } 1561 }
1558 1562
1559 kernfs_remove_by_name(cgrp->kn, cgroup_file_name(cgrp, cft, name)); 1563 kernfs_remove_by_name(cgrp->kn, cgroup_file_name(cgrp, cft, name));
@@ -3532,6 +3536,12 @@ static int cgroup_kn_set_ugid(struct kernfs_node *kn)
3532 return kernfs_setattr(kn, &iattr); 3536 return kernfs_setattr(kn, &iattr);
3533} 3537}
3534 3538
3539static void cgroup_file_notify_timer(struct timer_list *timer)
3540{
3541 cgroup_file_notify(container_of(timer, struct cgroup_file,
3542 notify_timer));
3543}
3544
3535static int cgroup_add_file(struct cgroup_subsys_state *css, struct cgroup *cgrp, 3545static int cgroup_add_file(struct cgroup_subsys_state *css, struct cgroup *cgrp,
3536 struct cftype *cft) 3546 struct cftype *cft)
3537{ 3547{
@@ -3558,6 +3568,8 @@ static int cgroup_add_file(struct cgroup_subsys_state *css, struct cgroup *cgrp,
3558 if (cft->file_offset) { 3568 if (cft->file_offset) {
3559 struct cgroup_file *cfile = (void *)css + cft->file_offset; 3569 struct cgroup_file *cfile = (void *)css + cft->file_offset;
3560 3570
3571 timer_setup(&cfile->notify_timer, cgroup_file_notify_timer, 0);
3572
3561 spin_lock_irq(&cgroup_file_kn_lock); 3573 spin_lock_irq(&cgroup_file_kn_lock);
3562 cfile->kn = kn; 3574 cfile->kn = kn;
3563 spin_unlock_irq(&cgroup_file_kn_lock); 3575 spin_unlock_irq(&cgroup_file_kn_lock);
@@ -3807,8 +3819,17 @@ void cgroup_file_notify(struct cgroup_file *cfile)
3807 unsigned long flags; 3819 unsigned long flags;
3808 3820
3809 spin_lock_irqsave(&cgroup_file_kn_lock, flags); 3821 spin_lock_irqsave(&cgroup_file_kn_lock, flags);
3810 if (cfile->kn) 3822 if (cfile->kn) {
3811 kernfs_notify(cfile->kn); 3823 unsigned long last = cfile->notified_at;
3824 unsigned long next = last + CGROUP_FILE_NOTIFY_MIN_INTV;
3825
3826 if (time_in_range(jiffies, last, next)) {
3827 timer_reduce(&cfile->notify_timer, next);
3828 } else {
3829 kernfs_notify(cfile->kn);
3830 cfile->notified_at = jiffies;
3831 }
3832 }
3812 spin_unlock_irqrestore(&cgroup_file_kn_lock, flags); 3833 spin_unlock_irqrestore(&cgroup_file_kn_lock, flags);
3813} 3834}
3814 3835