Commit 0bc77381c1b1600e659eb7322c39d1753615722d

Authored by Jeff Layton
Committed by Al Viro
1 parent 99b072bb38

seq_file: add seq_list_*_percpu helpers

When we convert the file_lock_list to a set of percpu lists, we'll need
a way to iterate over them in order to output /proc/locks info. Add
some seq_list_*_percpu helpers to handle that.

Signed-off-by: Jeff Layton <jlayton@redhat.com>
Acked-by: J. Bruce Fields <bfields@fieldses.org>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Showing 2 changed files with 60 additions and 0 deletions Side-by-side Diff

... ... @@ -921,4 +921,58 @@
921 921 return rcu_dereference(node->next);
922 922 }
923 923 EXPORT_SYMBOL(seq_hlist_next_rcu);
  924 +
  925 +/**
  926 + * seq_hlist_start_precpu - start an iteration of a percpu hlist array
  927 + * @head: pointer to percpu array of struct hlist_heads
  928 + * @cpu: pointer to cpu "cursor"
  929 + * @pos: start position of sequence
  930 + *
  931 + * Called at seq_file->op->start().
  932 + */
  933 +struct hlist_node *
  934 +seq_hlist_start_percpu(struct hlist_head __percpu *head, int *cpu, loff_t pos)
  935 +{
  936 + struct hlist_node *node;
  937 +
  938 + for_each_possible_cpu(*cpu) {
  939 + hlist_for_each(node, per_cpu_ptr(head, *cpu)) {
  940 + if (pos-- == 0)
  941 + return node;
  942 + }
  943 + }
  944 + return NULL;
  945 +}
  946 +EXPORT_SYMBOL(seq_hlist_start_percpu);
  947 +
  948 +/**
  949 + * seq_hlist_next_percpu - move to the next position of the percpu hlist array
  950 + * @v: pointer to current hlist_node
  951 + * @head: pointer to percpu array of struct hlist_heads
  952 + * @cpu: pointer to cpu "cursor"
  953 + * @pos: start position of sequence
  954 + *
  955 + * Called at seq_file->op->next().
  956 + */
  957 +struct hlist_node *
  958 +seq_hlist_next_percpu(void *v, struct hlist_head __percpu *head,
  959 + int *cpu, loff_t *pos)
  960 +{
  961 + struct hlist_node *node = v;
  962 +
  963 + ++*pos;
  964 +
  965 + if (node->next)
  966 + return node->next;
  967 +
  968 + for (*cpu = cpumask_next(*cpu, cpu_possible_mask); *cpu < nr_cpu_ids;
  969 + *cpu = cpumask_next(*cpu, cpu_possible_mask)) {
  970 + struct hlist_head *bucket = per_cpu_ptr(head, *cpu);
  971 +
  972 + if (!hlist_empty(bucket))
  973 + return bucket->first;
  974 + }
  975 + return NULL;
  976 +}
  977 +EXPORT_SYMBOL(seq_hlist_next_percpu);
include/linux/seq_file.h
... ... @@ -173,5 +173,11 @@
173 173 extern struct hlist_node *seq_hlist_next_rcu(void *v,
174 174 struct hlist_head *head,
175 175 loff_t *ppos);
  176 +
  177 +/* Helpers for iterating over per-cpu hlist_head-s in seq_files */
  178 +extern struct hlist_node *seq_hlist_start_percpu(struct hlist_head __percpu *head, int *cpu, loff_t pos);
  179 +
  180 +extern struct hlist_node *seq_hlist_next_percpu(void *v, struct hlist_head __percpu *head, int *cpu, loff_t *pos);
  181 +
176 182 #endif