diff options
author | WANG Cong <xiyou.wangcong@gmail.com> | 2017-07-10 13:05:50 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2017-07-11 16:41:57 -0400 |
commit | ffa423fb3251f8737303ffc3b0659e86e501808e (patch) | |
tree | 0d93e56751fc63134f41f2bbb5e38963c6281aa4 /drivers/net/tap.c | |
parent | 6a146f3a5894b751cef16feb3d7903e45e3c445c (diff) |
tap: convert a mutex to a spinlock
We are not allowed to block on the RCU reader side, so can't
just hold the mutex as before. As a quick fix, convert it to
a spinlock.
Fixes: d9f1f61c0801 ("tap: Extending tap device create/destroy APIs")
Reported-by: Christian Borntraeger <borntraeger@de.ibm.com>
Tested-by: Christian Borntraeger <borntraeger@de.ibm.com>
Cc: Sainath Grandhi <sainath.grandhi@intel.com>
Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/tap.c')
-rw-r--r-- | drivers/net/tap.c | 18 |
1 files changed, 9 insertions, 9 deletions
diff --git a/drivers/net/tap.c b/drivers/net/tap.c index 9af3239d6ad5..3570c7576993 100644 --- a/drivers/net/tap.c +++ b/drivers/net/tap.c | |||
@@ -106,7 +106,7 @@ struct major_info { | |||
106 | struct rcu_head rcu; | 106 | struct rcu_head rcu; |
107 | dev_t major; | 107 | dev_t major; |
108 | struct idr minor_idr; | 108 | struct idr minor_idr; |
109 | struct mutex minor_lock; | 109 | spinlock_t minor_lock; |
110 | const char *device_name; | 110 | const char *device_name; |
111 | struct list_head next; | 111 | struct list_head next; |
112 | }; | 112 | }; |
@@ -416,15 +416,15 @@ int tap_get_minor(dev_t major, struct tap_dev *tap) | |||
416 | goto unlock; | 416 | goto unlock; |
417 | } | 417 | } |
418 | 418 | ||
419 | mutex_lock(&tap_major->minor_lock); | 419 | spin_lock(&tap_major->minor_lock); |
420 | retval = idr_alloc(&tap_major->minor_idr, tap, 1, TAP_NUM_DEVS, GFP_KERNEL); | 420 | retval = idr_alloc(&tap_major->minor_idr, tap, 1, TAP_NUM_DEVS, GFP_ATOMIC); |
421 | if (retval >= 0) { | 421 | if (retval >= 0) { |
422 | tap->minor = retval; | 422 | tap->minor = retval; |
423 | } else if (retval == -ENOSPC) { | 423 | } else if (retval == -ENOSPC) { |
424 | netdev_err(tap->dev, "Too many tap devices\n"); | 424 | netdev_err(tap->dev, "Too many tap devices\n"); |
425 | retval = -EINVAL; | 425 | retval = -EINVAL; |
426 | } | 426 | } |
427 | mutex_unlock(&tap_major->minor_lock); | 427 | spin_unlock(&tap_major->minor_lock); |
428 | 428 | ||
429 | unlock: | 429 | unlock: |
430 | rcu_read_unlock(); | 430 | rcu_read_unlock(); |
@@ -442,12 +442,12 @@ void tap_free_minor(dev_t major, struct tap_dev *tap) | |||
442 | goto unlock; | 442 | goto unlock; |
443 | } | 443 | } |
444 | 444 | ||
445 | mutex_lock(&tap_major->minor_lock); | 445 | spin_lock(&tap_major->minor_lock); |
446 | if (tap->minor) { | 446 | if (tap->minor) { |
447 | idr_remove(&tap_major->minor_idr, tap->minor); | 447 | idr_remove(&tap_major->minor_idr, tap->minor); |
448 | tap->minor = 0; | 448 | tap->minor = 0; |
449 | } | 449 | } |
450 | mutex_unlock(&tap_major->minor_lock); | 450 | spin_unlock(&tap_major->minor_lock); |
451 | 451 | ||
452 | unlock: | 452 | unlock: |
453 | rcu_read_unlock(); | 453 | rcu_read_unlock(); |
@@ -467,13 +467,13 @@ static struct tap_dev *dev_get_by_tap_file(int major, int minor) | |||
467 | goto unlock; | 467 | goto unlock; |
468 | } | 468 | } |
469 | 469 | ||
470 | mutex_lock(&tap_major->minor_lock); | 470 | spin_lock(&tap_major->minor_lock); |
471 | tap = idr_find(&tap_major->minor_idr, minor); | 471 | tap = idr_find(&tap_major->minor_idr, minor); |
472 | if (tap) { | 472 | if (tap) { |
473 | dev = tap->dev; | 473 | dev = tap->dev; |
474 | dev_hold(dev); | 474 | dev_hold(dev); |
475 | } | 475 | } |
476 | mutex_unlock(&tap_major->minor_lock); | 476 | spin_unlock(&tap_major->minor_lock); |
477 | 477 | ||
478 | unlock: | 478 | unlock: |
479 | rcu_read_unlock(); | 479 | rcu_read_unlock(); |
@@ -1244,7 +1244,7 @@ static int tap_list_add(dev_t major, const char *device_name) | |||
1244 | tap_major->major = MAJOR(major); | 1244 | tap_major->major = MAJOR(major); |
1245 | 1245 | ||
1246 | idr_init(&tap_major->minor_idr); | 1246 | idr_init(&tap_major->minor_idr); |
1247 | mutex_init(&tap_major->minor_lock); | 1247 | spin_lock_init(&tap_major->minor_lock); |
1248 | 1248 | ||
1249 | tap_major->device_name = device_name; | 1249 | tap_major->device_name = device_name; |
1250 | 1250 | ||