On Mon, Mar 15, 2021 at 12:07:56PM +0000, David Howells wrote: > Use the mounts_to_id xarray added to the mount namespace to perform You called it mounts_by_id in the last patch ... > Since it doesn't trawl a standard list_head, but rather uses xarray, this > could be done under the RCU read lock only. To do this, we would need to > hide mounts that are in the process of being inserted into the tree by > marking them in the xarray itself or using a mount flag. > /* iterator; we want it to have access to namespace_sem, thus here... */ > static void *m_start(struct seq_file *m, loff_t *pos) > { > - struct proc_mounts *p = m->private; > - struct list_head *prev; > + struct proc_mounts *state = m->private; > + void *entry; > > down_read(&namespace_sem); > - if (!*pos) { > - prev = &p->ns->list; > - } else { > - prev = &p->cursor.mnt_list; > + state->xas = (struct xa_state) __XA_STATE(&state->ns->mounts_by_id, *pos, 0, 0); > > - /* Read after we'd reached the end? */ > - if (list_empty(prev)) > - return NULL; > - } > + entry = xas_find(&state->xas, ULONG_MAX); I know you haven't enabled enough debugging because this will assert that either the RCU read lock or the xa_lock is held to prevent xa_nodes from disappearing underneath us. Why do you want to use an xa_state for this? This is /proc, so efficiency isn't the highest priority. I'd just use xa_find(), and then you don't need to care about an xa_state or locking -- it handles taking the rcu read lock for you. > + while (entry && xas_invalid(entry)) I've never seen anybody make that mistake before. Good one. Not sure if there's anything I can do to prevent it in future. > + entry = xas_next_entry(&state->xas, ULONG_MAX);