114 lines
3.6 KiB
Diff
114 lines
3.6 KiB
Diff
From 10dbf1ed93bf3b5e4708bb97a2d690135db04f70 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 235/325] net: Add a mutex around devnet_rename_seq
|
|
Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/4.19/older/patches-4.19.115-rt48.tar.xz
|
|
|
|
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 81174cf6bf9a..be33b775565e 100644
|
|
--- a/net/core/dev.c
|
|
+++ b/net/core/dev.c
|
|
@@ -196,6 +196,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)
|
|
{
|
|
@@ -921,7 +922,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;
|
|
}
|
|
|
|
@@ -1198,20 +1200,17 @@ int dev_change_name(struct net_device *dev, const char *newname)
|
|
likely(!(dev->priv_flags & IFF_LIVE_RENAME_OK)))
|
|
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);
|
|
@@ -1224,11 +1223,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);
|
|
|
|
@@ -1249,7 +1249,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;
|
|
@@ -1262,6 +1263,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.25.1
|
|
|