forked from rrcarlosr/Jetpack
113 lines
3.4 KiB
Diff
113 lines
3.4 KiB
Diff
From eec99921cbbab034c7ff4abb934f8613fd465954 Mon Sep 17 00:00:00 2001
|
|
From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
|
|
Date: Wed, 20 Mar 2013 18:06:20 +0100
|
|
Subject: [PATCH 293/352] net: Add a mutex around devnet_rename_seq
|
|
|
|
On RT write_seqcount_begin() disables preemption and device_rename()
|
|
allocates memory with GFP_KERNEL and grabs later the sysfs_mutex
|
|
mutex. Serialize with a mutex and add use the non preemption disabling
|
|
__write_seqcount_begin().
|
|
|
|
To avoid writer starvation, let the reader grab the mutex and release
|
|
it when it detects a writer in progress. This keeps the normal case
|
|
(no reader on the fly) fast.
|
|
|
|
[ tglx: Instead of replacing the seqcount by a mutex, add the mutex ]
|
|
|
|
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
|
|
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
|
|
---
|
|
net/core/dev.c | 34 ++++++++++++++++++++--------------
|
|
1 file changed, 20 insertions(+), 14 deletions(-)
|
|
|
|
diff --git a/net/core/dev.c b/net/core/dev.c
|
|
index 0e67996..9ccac1a 100644
|
|
--- a/net/core/dev.c
|
|
+++ b/net/core/dev.c
|
|
@@ -190,6 +190,7 @@ static unsigned int napi_gen_id = NR_CPUS;
|
|
static DEFINE_READ_MOSTLY_HASHTABLE(napi_hash, 8);
|
|
|
|
static seqcount_t devnet_rename_seq;
|
|
+static DEFINE_MUTEX(devnet_rename_mutex);
|
|
|
|
static inline void dev_base_seq_inc(struct net *net)
|
|
{
|
|
@@ -888,7 +889,8 @@ int netdev_get_name(struct net *net, char *name, int ifindex)
|
|
strcpy(name, dev->name);
|
|
rcu_read_unlock();
|
|
if (read_seqcount_retry(&devnet_rename_seq, seq)) {
|
|
- cond_resched();
|
|
+ mutex_lock(&devnet_rename_mutex);
|
|
+ mutex_unlock(&devnet_rename_mutex);
|
|
goto retry;
|
|
}
|
|
|
|
@@ -1157,20 +1159,17 @@ int dev_change_name(struct net_device *dev, const char *newname)
|
|
if (dev->flags & IFF_UP)
|
|
return -EBUSY;
|
|
|
|
- write_seqcount_begin(&devnet_rename_seq);
|
|
+ mutex_lock(&devnet_rename_mutex);
|
|
+ __raw_write_seqcount_begin(&devnet_rename_seq);
|
|
|
|
- if (strncmp(newname, dev->name, IFNAMSIZ) == 0) {
|
|
- write_seqcount_end(&devnet_rename_seq);
|
|
- return 0;
|
|
- }
|
|
+ if (strncmp(newname, dev->name, IFNAMSIZ) == 0)
|
|
+ goto outunlock;
|
|
|
|
memcpy(oldname, dev->name, IFNAMSIZ);
|
|
|
|
err = dev_get_valid_name(net, dev, newname);
|
|
- if (err < 0) {
|
|
- write_seqcount_end(&devnet_rename_seq);
|
|
- return err;
|
|
- }
|
|
+ if (err < 0)
|
|
+ goto outunlock;
|
|
|
|
if (oldname[0] && !strchr(oldname, '%'))
|
|
netdev_info(dev, "renamed from %s\n", oldname);
|
|
@@ -1183,11 +1182,12 @@ int dev_change_name(struct net_device *dev, const char *newname)
|
|
if (ret) {
|
|
memcpy(dev->name, oldname, IFNAMSIZ);
|
|
dev->name_assign_type = old_assign_type;
|
|
- write_seqcount_end(&devnet_rename_seq);
|
|
- return ret;
|
|
+ err = ret;
|
|
+ goto outunlock;
|
|
}
|
|
|
|
- write_seqcount_end(&devnet_rename_seq);
|
|
+ __raw_write_seqcount_end(&devnet_rename_seq);
|
|
+ mutex_unlock(&devnet_rename_mutex);
|
|
|
|
netdev_adjacent_rename_links(dev, oldname);
|
|
|
|
@@ -1208,7 +1208,8 @@ int dev_change_name(struct net_device *dev, const char *newname)
|
|
/* err >= 0 after dev_alloc_name() or stores the first errno */
|
|
if (err >= 0) {
|
|
err = ret;
|
|
- write_seqcount_begin(&devnet_rename_seq);
|
|
+ mutex_lock(&devnet_rename_mutex);
|
|
+ __raw_write_seqcount_begin(&devnet_rename_seq);
|
|
memcpy(dev->name, oldname, IFNAMSIZ);
|
|
memcpy(oldname, newname, IFNAMSIZ);
|
|
dev->name_assign_type = old_assign_type;
|
|
@@ -1221,6 +1222,11 @@ int dev_change_name(struct net_device *dev, const char *newname)
|
|
}
|
|
|
|
return err;
|
|
+
|
|
+outunlock:
|
|
+ __raw_write_seqcount_end(&devnet_rename_seq);
|
|
+ mutex_unlock(&devnet_rename_mutex);
|
|
+ return err;
|
|
}
|
|
|
|
/**
|
|
--
|
|
2.7.4
|
|
|