Arvind M | 8e87d85 | 2018-01-29 00:04:29 -0800 | [diff] [blame] | 1 | From 65d10089f19da8c932b4990082f33e9dc1b8d8c6 Mon Sep 17 00:00:00 2001 |
Allen Martin | 685e0f8 | 2016-07-26 19:34:29 -0700 | [diff] [blame] | 2 | From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> |
| 3 | Date: Wed, 20 Mar 2013 18:06:20 +0100 |
Arvind M | 10268e7 | 2017-12-04 22:18:06 -0800 | [diff] [blame] | 4 | Subject: [PATCH 229/366] net: Add a mutex around devnet_rename_seq |
Allen Martin | 685e0f8 | 2016-07-26 19:34:29 -0700 | [diff] [blame] | 5 | |
| 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(). |
| 10 | |
| 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. |
| 14 | |
| 15 | [ tglx: Instead of replacing the seqcount by a mutex, add the mutex ] |
| 16 | |
| 17 | Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> |
| 18 | Signed-off-by: Thomas Gleixner <tglx@linutronix.de> |
Allen Martin | 685e0f8 | 2016-07-26 19:34:29 -0700 | [diff] [blame] | 19 | --- |
| 20 | net/core/dev.c | 34 ++++++++++++++++++++-------------- |
| 21 | 1 file changed, 20 insertions(+), 14 deletions(-) |
| 22 | |
| 23 | diff --git a/net/core/dev.c b/net/core/dev.c |
Ishan Mittal | b799826 | 2017-01-17 16:11:50 +0530 | [diff] [blame] | 24 | index 437e5fe..45b7dc7 100644 |
Allen Martin | 685e0f8 | 2016-07-26 19:34:29 -0700 | [diff] [blame] | 25 | --- a/net/core/dev.c |
| 26 | +++ b/net/core/dev.c |
| 27 | @@ -186,6 +186,7 @@ static unsigned int napi_gen_id; |
| 28 | static DEFINE_HASHTABLE(napi_hash, 8); |
| 29 | |
| 30 | static seqcount_t devnet_rename_seq; |
| 31 | +static DEFINE_MUTEX(devnet_rename_mutex); |
| 32 | |
| 33 | static inline void dev_base_seq_inc(struct net *net) |
| 34 | { |
| 35 | @@ -884,7 +885,8 @@ retry: |
| 36 | strcpy(name, dev->name); |
| 37 | rcu_read_unlock(); |
| 38 | if (read_seqcount_retry(&devnet_rename_seq, seq)) { |
| 39 | - cond_resched(); |
| 40 | + mutex_lock(&devnet_rename_mutex); |
| 41 | + mutex_unlock(&devnet_rename_mutex); |
| 42 | goto retry; |
| 43 | } |
| 44 | |
| 45 | @@ -1153,20 +1155,17 @@ int dev_change_name(struct net_device *dev, const char *newname) |
| 46 | if (dev->flags & IFF_UP) |
| 47 | return -EBUSY; |
| 48 | |
| 49 | - write_seqcount_begin(&devnet_rename_seq); |
| 50 | + mutex_lock(&devnet_rename_mutex); |
| 51 | + __raw_write_seqcount_begin(&devnet_rename_seq); |
| 52 | |
| 53 | - if (strncmp(newname, dev->name, IFNAMSIZ) == 0) { |
| 54 | - write_seqcount_end(&devnet_rename_seq); |
| 55 | - return 0; |
| 56 | - } |
| 57 | + if (strncmp(newname, dev->name, IFNAMSIZ) == 0) |
| 58 | + goto outunlock; |
| 59 | |
| 60 | memcpy(oldname, dev->name, IFNAMSIZ); |
| 61 | |
| 62 | err = dev_get_valid_name(net, dev, newname); |
| 63 | - if (err < 0) { |
| 64 | - write_seqcount_end(&devnet_rename_seq); |
| 65 | - return err; |
| 66 | - } |
| 67 | + if (err < 0) |
| 68 | + goto outunlock; |
| 69 | |
| 70 | if (oldname[0] && !strchr(oldname, '%')) |
| 71 | netdev_info(dev, "renamed from %s\n", oldname); |
| 72 | @@ -1179,11 +1178,12 @@ rollback: |
| 73 | if (ret) { |
| 74 | memcpy(dev->name, oldname, IFNAMSIZ); |
| 75 | dev->name_assign_type = old_assign_type; |
| 76 | - write_seqcount_end(&devnet_rename_seq); |
| 77 | - return ret; |
| 78 | + err = ret; |
| 79 | + goto outunlock; |
| 80 | } |
| 81 | |
| 82 | - write_seqcount_end(&devnet_rename_seq); |
| 83 | + __raw_write_seqcount_end(&devnet_rename_seq); |
| 84 | + mutex_unlock(&devnet_rename_mutex); |
| 85 | |
| 86 | netdev_adjacent_rename_links(dev, oldname); |
| 87 | |
| 88 | @@ -1204,7 +1204,8 @@ rollback: |
| 89 | /* err >= 0 after dev_alloc_name() or stores the first errno */ |
| 90 | if (err >= 0) { |
| 91 | err = ret; |
| 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: |
| 99 | } |
| 100 | |
| 101 | return err; |
| 102 | + |
| 103 | +outunlock: |
| 104 | + __raw_write_seqcount_end(&devnet_rename_seq); |
| 105 | + mutex_unlock(&devnet_rename_mutex); |
| 106 | + return err; |
| 107 | } |
| 108 | |
| 109 | /** |
| 110 | -- |
Arvind M | 10268e7 | 2017-12-04 22:18:06 -0800 | [diff] [blame] | 111 | 1.9.1 |
Allen Martin | 685e0f8 | 2016-07-26 19:34:29 -0700 | [diff] [blame] | 112 | |