Commit 0bc77381c1b1600e659eb7322c39d1753615722d
Committed by
Al Viro
1 parent
99b072bb38
Exists in
master
and in
20 other branches
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
fs/seq_file.c
... | ... | @@ -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 |