Commit c7999c3627bc6d49aa6fb9451063938cfd2c2082

Authored by Al Viro
1 parent f2ebb3a921

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

... ... @@ -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))
... ... @@ -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)
... ... @@ -267,6 +267,7 @@
267 267 p->root = root;
268 268 p->m.poll_event = ns->event;
269 269 p->show = show;
  270 + p->cached_event = ~0ULL;
270 271  
271 272 return 0;
272 273