From: Amir Goldstein <amir73il@gmail.com>
To: Jan Kara <jack@suse.cz>
Cc: linux-fsdevel@vger.kernel.org
Subject: [PATCH 6/7] fanotify: mix event info into merge key hash
Date: Tue, 2 Feb 2021 18:20:09 +0200 [thread overview]
Message-ID: <20210202162010.305971-7-amir73il@gmail.com> (raw)
In-Reply-To: <20210202162010.305971-1-amir73il@gmail.com>
Improve the balance of hashed queue lists by mixing more event info
relevant for merge.
For example, all FAN_CREATE name events in the same dir used to have the
same merge key based on the dir inode. With this change the created
file name is mixed into the merge key.
Signed-off-by: Amir Goldstein <amir73il@gmail.com>
---
fs/notify/fanotify/fanotify.c | 33 +++++++++++++++++++++++++++------
fs/notify/fanotify/fanotify.h | 20 +++++++++++++++++---
2 files changed, 44 insertions(+), 9 deletions(-)
diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c
index 6d3807012851..b19fef1c6f64 100644
--- a/fs/notify/fanotify/fanotify.c
+++ b/fs/notify/fanotify/fanotify.c
@@ -14,6 +14,7 @@
#include <linux/audit.h>
#include <linux/sched/mm.h>
#include <linux/statfs.h>
+#include <linux/stringhash.h>
#include "fanotify.h"
@@ -443,6 +444,10 @@ static struct fanotify_event *fanotify_alloc_path_event(const struct path *path,
pevent->path = *path;
path_get(path);
+ /* Mix path info into event merge key */
+ pevent->fae.info_hash = hash_ptr(path->dentry, 32) ^
+ hash_ptr(path->mnt, 32);
+
return &pevent->fae;
}
@@ -461,6 +466,9 @@ static struct fanotify_event *fanotify_alloc_perm_event(const struct path *path,
pevent->path = *path;
path_get(path);
+ /* Permission events are not merged */
+ pevent->fae.info_hash = 0;
+
return &pevent->fae;
}
@@ -469,6 +477,7 @@ static struct fanotify_event *fanotify_alloc_fid_event(struct inode *id,
gfp_t gfp)
{
struct fanotify_fid_event *ffe;
+ struct fanotify_fh *fh;
ffe = kmem_cache_alloc(fanotify_fid_event_cachep, gfp);
if (!ffe)
@@ -476,8 +485,11 @@ static struct fanotify_event *fanotify_alloc_fid_event(struct inode *id,
ffe->fae.type = FANOTIFY_EVENT_TYPE_FID;
ffe->fsid = *fsid;
- fanotify_encode_fh(&ffe->object_fh, id, fanotify_encode_fh_len(id),
- gfp);
+ fh = &ffe->object_fh;
+ fanotify_encode_fh(fh, id, fanotify_encode_fh_len(id), gfp);
+
+ /* Mix fsid+fid info into event merge key */
+ ffe->fae.info_hash = full_name_hash(ffe->fskey, fanotify_fh_buf(fh), fh->len);
return &ffe->fae;
}
@@ -517,6 +529,9 @@ static struct fanotify_event *fanotify_alloc_name_event(struct inode *id,
if (file_name)
fanotify_info_copy_name(info, file_name);
+ /* Mix fsid+dfid+name+fid info into event merge key */
+ fne->fae.info_hash = full_name_hash(fne->fskey, info->buf, fanotify_info_len(info));
+
pr_debug("%s: ino=%lu size=%u dir_fh_len=%u child_fh_len=%u name_len=%u name='%.*s'\n",
__func__, id->i_ino, size, dir_fh_len, child_fh_len,
info->name_len, info->name_len, fanotify_info_name(info));
@@ -539,6 +554,8 @@ static struct fanotify_event *fanotify_alloc_event(struct fsnotify_group *group,
struct mem_cgroup *old_memcg;
struct inode *child = NULL;
bool name_event = false;
+ unsigned int hash = 0;
+ struct pid *pid;
if ((fid_mode & FAN_REPORT_DIR_FID) && dirid) {
/*
@@ -606,13 +623,17 @@ static struct fanotify_event *fanotify_alloc_event(struct fsnotify_group *group,
* Use the victim inode instead of the watching inode as the id for
* event queue, so event reported on parent is merged with event
* reported on child when both directory and child watches exist.
- * Reduce object id to 32bit hash for hashed queue merge.
+ * Reduce object id and event info to 32bit hash for hashed queue merge.
*/
- fanotify_init_event(event, hash_ptr(id, 32), mask);
+ hash = event->info_hash ^ hash_ptr(id, 32);
if (FAN_GROUP_FLAG(group, FAN_REPORT_TID))
- event->pid = get_pid(task_pid(current));
+ pid = get_pid(task_pid(current));
else
- event->pid = get_pid(task_tgid(current));
+ pid = get_pid(task_tgid(current));
+ /* Mix pid info into event merge key */
+ hash ^= hash_ptr(pid, 32);
+ fanotify_init_event(event, hash, mask);
+ event->pid = pid;
out:
set_active_memcg(old_memcg);
diff --git a/fs/notify/fanotify/fanotify.h b/fs/notify/fanotify/fanotify.h
index 2e856372ffc8..522fb1a68b30 100644
--- a/fs/notify/fanotify/fanotify.h
+++ b/fs/notify/fanotify/fanotify.h
@@ -115,6 +115,11 @@ static inline void fanotify_info_init(struct fanotify_info *info)
info->name_len = 0;
}
+static inline unsigned int fanotify_info_len(struct fanotify_info *info)
+{
+ return info->dir_fh_totlen + info->file_fh_totlen + info->name_len;
+}
+
static inline void fanotify_info_copy_name(struct fanotify_info *info,
const struct qstr *name)
{
@@ -138,7 +143,10 @@ enum fanotify_event_type {
};
struct fanotify_event {
- struct fsnotify_event fse;
+ union {
+ struct fsnotify_event fse;
+ unsigned int info_hash;
+ };
u32 mask;
enum fanotify_event_type type;
struct pid *pid;
@@ -154,7 +162,10 @@ static inline void fanotify_init_event(struct fanotify_event *event,
struct fanotify_fid_event {
struct fanotify_event fae;
- __kernel_fsid_t fsid;
+ union {
+ __kernel_fsid_t fsid;
+ void *fskey; /* 64 or 32 bits of fsid used for salt */
+ };
struct fanotify_fh object_fh;
/* Reserve space in object_fh.buf[] - access with fanotify_fh_buf() */
unsigned char _inline_fh_buf[FANOTIFY_INLINE_FH_LEN];
@@ -168,7 +179,10 @@ FANOTIFY_FE(struct fanotify_event *event)
struct fanotify_name_event {
struct fanotify_event fae;
- __kernel_fsid_t fsid;
+ union {
+ __kernel_fsid_t fsid;
+ void *fskey; /* 64 or 32 bits of fsid used for salt */
+ };
struct fanotify_info info;
};
--
2.25.1
next prev parent reply other threads:[~2021-02-02 16:28 UTC|newest]
Thread overview: 36+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-02-02 16:20 [PATCH 0/7] Performance improvement for fanotify merge Amir Goldstein
2021-02-02 16:20 ` [PATCH 1/7] fsnotify: allow fsnotify_{peek,remove}_first_event with empty queue Amir Goldstein
2021-02-02 16:20 ` [PATCH 2/7] fsnotify: support hashed notification queue Amir Goldstein
2021-02-16 15:02 ` Jan Kara
2021-02-17 12:33 ` Amir Goldstein
2021-02-17 13:48 ` Jan Kara
2021-02-17 15:42 ` Amir Goldstein
2021-02-17 16:49 ` Jan Kara
2021-02-18 10:52 ` Amir Goldstein
2021-02-02 16:20 ` [PATCH 3/7] fsnotify: read events from hashed notification queue by order of insertion Amir Goldstein
2021-02-16 15:10 ` Jan Kara
2021-02-02 16:20 ` [PATCH 4/7] fanotify: enable hashed notification queue for FAN_CLASS_NOTIF groups Amir Goldstein
2021-02-02 16:20 ` [PATCH 5/7] fanotify: limit number of event merge attempts Amir Goldstein
2021-02-27 8:31 ` Amir Goldstein
2021-03-01 13:08 ` Jan Kara
2021-03-01 13:58 ` Amir Goldstein
2021-09-15 12:39 ` Amir Goldstein
2021-09-15 16:33 ` Jan Kara
2021-02-02 16:20 ` Amir Goldstein [this message]
2021-02-16 15:39 ` [PATCH 6/7] fanotify: mix event info into merge key hash Jan Kara
2021-02-17 10:13 ` Amir Goldstein
2021-02-18 10:46 ` Amir Goldstein
2021-02-18 11:11 ` Jan Kara
2021-02-18 12:17 ` Amir Goldstein
2021-02-02 16:20 ` [PATCH 7/7] fsnotify: print some debug stats on hashed queue overflow Amir Goldstein
2021-02-16 16:02 ` [PATCH 0/7] Performance improvement for fanotify merge Jan Kara
2021-02-17 10:52 ` Amir Goldstein
2021-02-17 11:25 ` Jan Kara
2021-02-18 10:56 ` Amir Goldstein
2021-02-18 11:15 ` Jan Kara
2021-02-18 12:35 ` Amir Goldstein
2021-02-19 10:15 ` Jan Kara
2021-02-19 10:21 ` Jan Kara
2021-02-19 13:38 ` Amir Goldstein
2021-02-21 12:53 ` Amir Goldstein
2021-02-22 9:29 ` Jan Kara
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210202162010.305971-7-amir73il@gmail.com \
--to=amir73il@gmail.com \
--cc=jack@suse.cz \
--cc=linux-fsdevel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).