Commit b8cd0ee8 authored by Amir Goldstein's avatar Amir Goldstein Committed by Jan Kara

fanotify: limit number of event merge attempts

Event merges are expensive when event queue size is large, so limit the
linear search to 128 merge tests.

In combination with 128 size hash table, there is a potential to merge
with up to 16K events in the hashed queue.

Link: https://lore.kernel.org/r/20210304104826.3993892-6-amir73il@gmail.comSigned-off-by: default avatarAmir Goldstein <amir73il@gmail.com>
Signed-off-by: default avatarJan Kara <jack@suse.cz>
parent 94e00d28
...@@ -148,6 +148,9 @@ static bool fanotify_should_merge(struct fanotify_event *old, ...@@ -148,6 +148,9 @@ static bool fanotify_should_merge(struct fanotify_event *old,
return false; return false;
} }
/* Limit event merges to limit CPU overhead per event */
#define FANOTIFY_MAX_MERGE_EVENTS 128
/* and the list better be locked by something too! */ /* and the list better be locked by something too! */
static int fanotify_merge(struct fsnotify_group *group, static int fanotify_merge(struct fsnotify_group *group,
struct fsnotify_event *event) struct fsnotify_event *event)
...@@ -155,6 +158,7 @@ static int fanotify_merge(struct fsnotify_group *group, ...@@ -155,6 +158,7 @@ static int fanotify_merge(struct fsnotify_group *group,
struct fanotify_event *old, *new = FANOTIFY_E(event); struct fanotify_event *old, *new = FANOTIFY_E(event);
unsigned int bucket = fanotify_event_hash_bucket(group, new); unsigned int bucket = fanotify_event_hash_bucket(group, new);
struct hlist_head *hlist = &group->fanotify_data.merge_hash[bucket]; struct hlist_head *hlist = &group->fanotify_data.merge_hash[bucket];
int i = 0;
pr_debug("%s: group=%p event=%p bucket=%u\n", __func__, pr_debug("%s: group=%p event=%p bucket=%u\n", __func__,
group, event, bucket); group, event, bucket);
...@@ -168,6 +172,8 @@ static int fanotify_merge(struct fsnotify_group *group, ...@@ -168,6 +172,8 @@ static int fanotify_merge(struct fsnotify_group *group,
return 0; return 0;
hlist_for_each_entry(old, hlist, merge_list) { hlist_for_each_entry(old, hlist, merge_list) {
if (++i > FANOTIFY_MAX_MERGE_EVENTS)
break;
if (fanotify_should_merge(old, new)) { if (fanotify_should_merge(old, new)) {
old->mask |= new->mask; old->mask |= new->mask;
return 1; return 1;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment