Skip to content

Commit 8988f11

Browse files
amir73iljankara
authored andcommitted
fanotify: reduce event objectid to 29-bit hash
objectid is only used by fanotify backend and it is just an optimization for event merge before comparing all fields in event. Move the objectid member from common struct fsnotify_event into struct fanotify_event and reduce it to 29-bit hash to cram it together with the 3-bit event type. Events of different types are never merged, so the combination of event type and hash form a 32-bit key for fast compare of events. This reduces the size of events by one pointer and paves the way for adding hashed queue support for fanotify. Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Amir Goldstein <[email protected]> Signed-off-by: Jan Kara <[email protected]>
1 parent 6f73171 commit 8988f11

File tree

5 files changed

+28
-22
lines changed

5 files changed

+28
-22
lines changed

fs/notify/fanotify/fanotify.c

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -88,16 +88,12 @@ static bool fanotify_name_event_equal(struct fanotify_name_event *fne1,
8888
return fanotify_info_equal(info1, info2);
8989
}
9090

91-
static bool fanotify_should_merge(struct fsnotify_event *old_fsn,
92-
struct fsnotify_event *new_fsn)
91+
static bool fanotify_should_merge(struct fanotify_event *old,
92+
struct fanotify_event *new)
9393
{
94-
struct fanotify_event *old, *new;
94+
pr_debug("%s: old=%p new=%p\n", __func__, old, new);
9595

96-
pr_debug("%s: old=%p new=%p\n", __func__, old_fsn, new_fsn);
97-
old = FANOTIFY_E(old_fsn);
98-
new = FANOTIFY_E(new_fsn);
99-
100-
if (old_fsn->objectid != new_fsn->objectid ||
96+
if (old->hash != new->hash ||
10197
old->type != new->type || old->pid != new->pid)
10298
return false;
10399

@@ -133,10 +129,9 @@ static bool fanotify_should_merge(struct fsnotify_event *old_fsn,
133129
static int fanotify_merge(struct list_head *list, struct fsnotify_event *event)
134130
{
135131
struct fsnotify_event *test_event;
136-
struct fanotify_event *new;
132+
struct fanotify_event *old, *new = FANOTIFY_E(event);
137133

138134
pr_debug("%s: list=%p event=%p\n", __func__, list, event);
139-
new = FANOTIFY_E(event);
140135

141136
/*
142137
* Don't merge a permission event with any other event so that we know
@@ -147,8 +142,9 @@ static int fanotify_merge(struct list_head *list, struct fsnotify_event *event)
147142
return 0;
148143

149144
list_for_each_entry_reverse(test_event, list, list) {
150-
if (fanotify_should_merge(test_event, event)) {
151-
FANOTIFY_E(test_event)->mask |= new->mask;
145+
old = FANOTIFY_E(test_event);
146+
if (fanotify_should_merge(old, new)) {
147+
old->mask |= new->mask;
152148
return 1;
153149
}
154150
}
@@ -533,6 +529,7 @@ static struct fanotify_event *fanotify_alloc_event(struct fsnotify_group *group,
533529
struct mem_cgroup *old_memcg;
534530
struct inode *child = NULL;
535531
bool name_event = false;
532+
unsigned int hash = 0;
536533

537534
if ((fid_mode & FAN_REPORT_DIR_FID) && dirid) {
538535
/*
@@ -600,8 +597,10 @@ static struct fanotify_event *fanotify_alloc_event(struct fsnotify_group *group,
600597
* Use the victim inode instead of the watching inode as the id for
601598
* event queue, so event reported on parent is merged with event
602599
* reported on child when both directory and child watches exist.
600+
* Hash object id for queue merge.
603601
*/
604-
fanotify_init_event(event, (unsigned long)id, mask);
602+
hash = hash_ptr(id, FANOTIFY_EVENT_HASH_BITS);
603+
fanotify_init_event(event, hash, mask);
605604
if (FAN_GROUP_FLAG(group, FAN_REPORT_TID))
606605
event->pid = get_pid(task_pid(current));
607606
else

fs/notify/fanotify/fanotify.h

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -135,19 +135,29 @@ enum fanotify_event_type {
135135
FANOTIFY_EVENT_TYPE_PATH,
136136
FANOTIFY_EVENT_TYPE_PATH_PERM,
137137
FANOTIFY_EVENT_TYPE_OVERFLOW, /* struct fanotify_event */
138+
__FANOTIFY_EVENT_TYPE_NUM
138139
};
139140

141+
#define FANOTIFY_EVENT_TYPE_BITS \
142+
(ilog2(__FANOTIFY_EVENT_TYPE_NUM - 1) + 1)
143+
#define FANOTIFY_EVENT_HASH_BITS \
144+
(32 - FANOTIFY_EVENT_TYPE_BITS)
145+
140146
struct fanotify_event {
141147
struct fsnotify_event fse;
142148
u32 mask;
143-
enum fanotify_event_type type;
149+
struct {
150+
unsigned int type : FANOTIFY_EVENT_TYPE_BITS;
151+
unsigned int hash : FANOTIFY_EVENT_HASH_BITS;
152+
};
144153
struct pid *pid;
145154
};
146155

147156
static inline void fanotify_init_event(struct fanotify_event *event,
148-
unsigned long id, u32 mask)
157+
unsigned int hash, u32 mask)
149158
{
150-
fsnotify_init_event(&event->fse, id);
159+
fsnotify_init_event(&event->fse);
160+
event->hash = hash;
151161
event->mask = mask;
152162
event->pid = NULL;
153163
}

fs/notify/inotify/inotify_fsnotify.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ int inotify_handle_inode_event(struct fsnotify_mark *inode_mark, u32 mask,
107107
mask &= ~IN_ISDIR;
108108

109109
fsn_event = &event->fse;
110-
fsnotify_init_event(fsn_event, 0);
110+
fsnotify_init_event(fsn_event);
111111
event->mask = mask;
112112
event->wd = i_mark->wd;
113113
event->sync_cookie = cookie;

fs/notify/inotify/inotify_user.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -641,7 +641,7 @@ static struct fsnotify_group *inotify_new_group(unsigned int max_events)
641641
return ERR_PTR(-ENOMEM);
642642
}
643643
group->overflow_event = &oevent->fse;
644-
fsnotify_init_event(group->overflow_event, 0);
644+
fsnotify_init_event(group->overflow_event);
645645
oevent->mask = FS_Q_OVERFLOW;
646646
oevent->wd = -1;
647647
oevent->sync_cookie = 0;

include/linux/fsnotify_backend.h

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,6 @@ struct fsnotify_ops {
167167
*/
168168
struct fsnotify_event {
169169
struct list_head list;
170-
unsigned long objectid; /* identifier for queue merges */
171170
};
172171

173172
/*
@@ -582,11 +581,9 @@ extern void fsnotify_put_mark(struct fsnotify_mark *mark);
582581
extern void fsnotify_finish_user_wait(struct fsnotify_iter_info *iter_info);
583582
extern bool fsnotify_prepare_user_wait(struct fsnotify_iter_info *iter_info);
584583

585-
static inline void fsnotify_init_event(struct fsnotify_event *event,
586-
unsigned long objectid)
584+
static inline void fsnotify_init_event(struct fsnotify_event *event)
587585
{
588586
INIT_LIST_HEAD(&event->list);
589-
event->objectid = objectid;
590587
}
591588

592589
#else

0 commit comments

Comments
 (0)