1 From 13422180504cf326a959fde38db6b76b7d72ee9e Mon Sep 17 00:00:00 2001
2 From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
3 Date: Wed, 20 Mar 2013 18:06:20 +0100
4 Subject: [PATCH 229/366] net: Add a mutex around devnet_rename_seq
6 On RT write_seqcount_begin() disables preemption and device_rename()
7 allocates memory with GFP_KERNEL and grabs later the sysfs_mutex
8 mutex. Serialize with a mutex and add use the non preemption disabling
9 __write_seqcount_begin().
11 To avoid writer starvation, let the reader grab the mutex and release
12 it when it detects a writer in progress. This keeps the normal case
13 (no reader on the fly) fast.
15 [ tglx: Instead of replacing the seqcount by a mutex, add the mutex ]
17 Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
18 Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
20 net/core/dev.c | 34 ++++++++++++++++++++--------------
21 1 file changed, 20 insertions(+), 14 deletions(-)
23 diff --git a/net/core/dev.c b/net/core/dev.c
24 index 437e5fe..45b7dc7 100644
27 @@ -186,6 +186,7 @@ static unsigned int napi_gen_id;
28 static DEFINE_HASHTABLE(napi_hash, 8);
30 static seqcount_t devnet_rename_seq;
31 +static DEFINE_MUTEX(devnet_rename_mutex);
33 static inline void dev_base_seq_inc(struct net *net)
35 @@ -884,7 +885,8 @@ retry:
36 strcpy(name, dev->name);
38 if (read_seqcount_retry(&devnet_rename_seq, seq)) {
40 + mutex_lock(&devnet_rename_mutex);
41 + mutex_unlock(&devnet_rename_mutex);
45 @@ -1153,20 +1155,17 @@ int dev_change_name(struct net_device *dev, const char *newname)
46 if (dev->flags & IFF_UP)
49 - write_seqcount_begin(&devnet_rename_seq);
50 + mutex_lock(&devnet_rename_mutex);
51 + __raw_write_seqcount_begin(&devnet_rename_seq);
53 - if (strncmp(newname, dev->name, IFNAMSIZ) == 0) {
54 - write_seqcount_end(&devnet_rename_seq);
57 + if (strncmp(newname, dev->name, IFNAMSIZ) == 0)
60 memcpy(oldname, dev->name, IFNAMSIZ);
62 err = dev_get_valid_name(net, dev, newname);
64 - write_seqcount_end(&devnet_rename_seq);
70 if (oldname[0] && !strchr(oldname, '%'))
71 netdev_info(dev, "renamed from %s\n", oldname);
72 @@ -1179,11 +1178,12 @@ rollback:
74 memcpy(dev->name, oldname, IFNAMSIZ);
75 dev->name_assign_type = old_assign_type;
76 - write_seqcount_end(&devnet_rename_seq);
82 - write_seqcount_end(&devnet_rename_seq);
83 + __raw_write_seqcount_end(&devnet_rename_seq);
84 + mutex_unlock(&devnet_rename_mutex);
86 netdev_adjacent_rename_links(dev, oldname);
88 @@ -1204,7 +1204,8 @@ rollback:
89 /* err >= 0 after dev_alloc_name() or stores the first errno */
92 - write_seqcount_begin(&devnet_rename_seq);
93 + mutex_lock(&devnet_rename_mutex);
94 + __raw_write_seqcount_begin(&devnet_rename_seq);
95 memcpy(dev->name, oldname, IFNAMSIZ);
96 memcpy(oldname, newname, IFNAMSIZ);
97 dev->name_assign_type = old_assign_type;
98 @@ -1217,6 +1218,11 @@ rollback:
104 + __raw_write_seqcount_end(&devnet_rename_seq);
105 + mutex_unlock(&devnet_rename_mutex);