Commit c7999c3627bc6d49aa6fb9451063938cfd2c2082
1 parent
f2ebb3a921
Exists in
master
and in
13 other branches
reduce m_start() cost...
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Showing 3 changed files with 23 additions and 4 deletions Side-by-side Diff
fs/mount.h
... | ... | @@ -10,7 +10,7 @@ |
10 | 10 | struct user_namespace *user_ns; |
11 | 11 | u64 seq; /* Sequence number to prevent loops */ |
12 | 12 | wait_queue_head_t poll; |
13 | - int event; | |
13 | + u64 event; | |
14 | 14 | }; |
15 | 15 | |
16 | 16 | struct mnt_pcp { |
... | ... | @@ -104,6 +104,9 @@ |
104 | 104 | struct mnt_namespace *ns; |
105 | 105 | struct path root; |
106 | 106 | int (*show)(struct seq_file *, struct vfsmount *); |
107 | + void *cached_mount; | |
108 | + u64 cached_event; | |
109 | + loff_t cached_index; | |
107 | 110 | }; |
108 | 111 | |
109 | 112 | #define proc_mounts(p) (container_of((p), struct proc_mounts, m)) |
fs/namespace.c
... | ... | @@ -52,7 +52,7 @@ |
52 | 52 | } |
53 | 53 | __setup("mphash_entries=", set_mphash_entries); |
54 | 54 | |
55 | -static int event; | |
55 | +static u64 event; | |
56 | 56 | static DEFINE_IDA(mnt_id_ida); |
57 | 57 | static DEFINE_IDA(mnt_group_ida); |
58 | 58 | static DEFINE_SPINLOCK(mnt_id_lock); |
59 | 59 | |
... | ... | @@ -1100,14 +1100,29 @@ |
1100 | 1100 | struct proc_mounts *p = proc_mounts(m); |
1101 | 1101 | |
1102 | 1102 | down_read(&namespace_sem); |
1103 | - return seq_list_start(&p->ns->list, *pos); | |
1103 | + if (p->cached_event == p->ns->event) { | |
1104 | + void *v = p->cached_mount; | |
1105 | + if (*pos == p->cached_index) | |
1106 | + return v; | |
1107 | + if (*pos == p->cached_index + 1) { | |
1108 | + v = seq_list_next(v, &p->ns->list, &p->cached_index); | |
1109 | + return p->cached_mount = v; | |
1110 | + } | |
1111 | + } | |
1112 | + | |
1113 | + p->cached_event = p->ns->event; | |
1114 | + p->cached_mount = seq_list_start(&p->ns->list, *pos); | |
1115 | + p->cached_index = *pos; | |
1116 | + return p->cached_mount; | |
1104 | 1117 | } |
1105 | 1118 | |
1106 | 1119 | static void *m_next(struct seq_file *m, void *v, loff_t *pos) |
1107 | 1120 | { |
1108 | 1121 | struct proc_mounts *p = proc_mounts(m); |
1109 | 1122 | |
1110 | - return seq_list_next(v, &p->ns->list, pos); | |
1123 | + p->cached_mount = seq_list_next(v, &p->ns->list, pos); | |
1124 | + p->cached_index = *pos; | |
1125 | + return p->cached_mount; | |
1111 | 1126 | } |
1112 | 1127 | |
1113 | 1128 | static void m_stop(struct seq_file *m, void *v) |