Skip to content

Commit 768f359

Browse files
xemulDavid S. Miller
authored andcommitted
[NETNS]: Cleanup list walking in setup_net and cleanup_net
I proposed introducing a list_for_each_entry_continue_reverse macro to be used in setup_net() when unrolling the failed ->init callback. Here is the macro and some more cleanup in the setup_net() itself to remove one variable from the stack :) The same thing is for the cleanup_net() - the existing list_for_each_entry_reverse() is used. Minor, but the code looks nicer. Signed-off-by: Pavel Emelyanov <[email protected]> Acked-by: "Eric W. Biederman" <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 1a348cc commit 768f359

File tree

2 files changed

+18
-8
lines changed

2 files changed

+18
-8
lines changed

include/linux/list.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -524,6 +524,20 @@ static inline void list_splice_init_rcu(struct list_head *list,
524524
prefetch(pos->member.next), &pos->member != (head); \
525525
pos = list_entry(pos->member.next, typeof(*pos), member))
526526

527+
/**
528+
* list_for_each_entry_continue_reverse - iterate backwards from the given point
529+
* @pos: the type * to use as a loop cursor.
530+
* @head: the head for your list.
531+
* @member: the name of the list_struct within the struct.
532+
*
533+
* Start to iterate over list of given type backwards, continuing after
534+
* the current position.
535+
*/
536+
#define list_for_each_entry_continue_reverse(pos, head, member) \
537+
for (pos = list_entry(pos->member.prev, typeof(*pos), member); \
538+
prefetch(pos->member.prev), &pos->member != (head); \
539+
pos = list_entry(pos->member.prev, typeof(*pos), member))
540+
527541
/**
528542
* list_for_each_entry_from - iterate over list of given type from the current point
529543
* @pos: the type * to use as a loop cursor.

net/core/net_namespace.c

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,6 @@ static void net_free(struct net *net)
5656
static void cleanup_net(struct work_struct *work)
5757
{
5858
struct pernet_operations *ops;
59-
struct list_head *ptr;
6059
struct net *net;
6160

6261
net = container_of(work, struct net, work);
@@ -69,8 +68,7 @@ static void cleanup_net(struct work_struct *work)
6968
net_unlock();
7069

7170
/* Run all of the network namespace exit methods */
72-
list_for_each_prev(ptr, &pernet_list) {
73-
ops = list_entry(ptr, struct pernet_operations, list);
71+
list_for_each_entry_reverse(ops, &pernet_list, list) {
7472
if (ops->exit)
7573
ops->exit(net);
7674
}
@@ -102,16 +100,14 @@ static int setup_net(struct net *net)
102100
{
103101
/* Must be called with net_mutex held */
104102
struct pernet_operations *ops;
105-
struct list_head *ptr;
106103
int error;
107104

108105
memset(net, 0, sizeof(struct net));
109106
atomic_set(&net->count, 1);
110107
atomic_set(&net->use_count, 0);
111108

112109
error = 0;
113-
list_for_each(ptr, &pernet_list) {
114-
ops = list_entry(ptr, struct pernet_operations, list);
110+
list_for_each_entry(ops, &pernet_list, list) {
115111
if (ops->init) {
116112
error = ops->init(net);
117113
if (error < 0)
@@ -120,12 +116,12 @@ static int setup_net(struct net *net)
120116
}
121117
out:
122118
return error;
119+
123120
out_undo:
124121
/* Walk through the list backwards calling the exit functions
125122
* for the pernet modules whose init functions did not fail.
126123
*/
127-
for (ptr = ptr->prev; ptr != &pernet_list; ptr = ptr->prev) {
128-
ops = list_entry(ptr, struct pernet_operations, list);
124+
list_for_each_entry_continue_reverse(ops, &pernet_list, list) {
129125
if (ops->exit)
130126
ops->exit(net);
131127
}

0 commit comments

Comments
 (0)