Skip to content

Commit 6c5c748

Browse files
tlfalcondavem330
authored andcommitted
ibmvnic: Convert reset work item mutex to spin lock
ibmvnic_reset can create and schedule a reset work item from an IRQ context, so do not use a mutex, which can sleep. Convert the reset work item mutex to a spin lock. Locking debugger generated the trace output below. BUG: sleeping function called from invalid context at kernel/locking/mutex.c:908 in_atomic(): 1, irqs_disabled(): 1, pid: 120, name: kworker/8:1 4 locks held by kworker/8:1/120: #0: 0000000017c05720 ((wq_completion)"events"){+.+.}, at: process_one_work+0x188/0x710 #1: 00000000ace90706 ((linkwatch_work).work){+.+.}, at: process_one_work+0x188/0x710 #2: 000000007632871f (rtnl_mutex){+.+.}, at: rtnl_lock+0x30/0x50 #3: 00000000fc36813a (&(&crq->lock)->rlock){..-.}, at: ibmvnic_tasklet+0x88/0x2010 [ibmvnic] irq event stamp: 26293 hardirqs last enabled at (26292): [<c000000000122468>] tasklet_action_common.isra.12+0x78/0x1c0 hardirqs last disabled at (26293): [<c000000000befce8>] _raw_spin_lock_irqsave+0x48/0xf0 softirqs last enabled at (26288): [<c000000000a8ac78>] dev_deactivate_queue.constprop.28+0xc8/0x160 softirqs last disabled at (26289): [<c0000000000306e0>] call_do_softirq+0x14/0x24 CPU: 8 PID: 120 Comm: kworker/8:1 Kdump: loaded Not tainted 4.20.0-rc6 #6 Workqueue: events linkwatch_event Call Trace: [c0000003fffa7a50] [c000000000bc83e4] dump_stack+0xe8/0x164 (unreliable) [c0000003fffa7aa0] [c00000000015ba0c] ___might_sleep+0x2dc/0x320 [c0000003fffa7b20] [c000000000be960c] __mutex_lock+0x8c/0xb40 [c0000003fffa7c30] [d000000006202ac8] ibmvnic_reset+0x78/0x330 [ibmvnic] [c0000003fffa7cc0] [d0000000062097f4] ibmvnic_tasklet+0x1054/0x2010 [ibmvnic] [c0000003fffa7e00] [c0000000001224c8] tasklet_action_common.isra.12+0xd8/0x1c0 [c0000003fffa7e60] [c000000000bf1238] __do_softirq+0x1a8/0x64c [c0000003fffa7f90] [c0000000000306e0] call_do_softirq+0x14/0x24 [c0000003f3f87980] [c00000000001ba50] do_softirq_own_stack+0x60/0xb0 [c0000003f3f879c0] [c0000000001218a8] do_softirq+0xa8/0x100 [c0000003f3f879f0] [c000000000121a74] __local_bh_enable_ip+0x174/0x180 [c0000003f3f87a60] [c000000000bf003c] _raw_spin_unlock_bh+0x5c/0x80 [c0000003f3f87a90] [c000000000a8ac78] dev_deactivate_queue.constprop.28+0xc8/0x160 [c0000003f3f87ad0] [c000000000a8c8b0] dev_deactivate_many+0xd0/0x520 [c0000003f3f87b70] [c000000000a8cd40] dev_deactivate+0x40/0x60 [c0000003f3f87ba0] [c000000000a5e0c4] linkwatch_do_dev+0x74/0xd0 [c0000003f3f87bd0] [c000000000a5e694] __linkwatch_run_queue+0x1a4/0x1f0 [c0000003f3f87c30] [c000000000a5e728] linkwatch_event+0x48/0x60 [c0000003f3f87c50] [c0000000001444e8] process_one_work+0x238/0x710 [c0000003f3f87d20] [c000000000144a48] worker_thread+0x88/0x4e0 [c0000003f3f87db0] [c00000000014e3a8] kthread+0x178/0x1c0 [c0000003f3f87e20] [c00000000000bfd0] ret_from_kernel_thread+0x5c/0x6c Signed-off-by: Thomas Falcon <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 5648451 commit 6c5c748

File tree

2 files changed

+10
-8
lines changed

2 files changed

+10
-8
lines changed

drivers/net/ethernet/ibm/ibmvnic.c

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1939,8 +1939,9 @@ static int do_hard_reset(struct ibmvnic_adapter *adapter,
19391939
static struct ibmvnic_rwi *get_next_rwi(struct ibmvnic_adapter *adapter)
19401940
{
19411941
struct ibmvnic_rwi *rwi;
1942+
unsigned long flags;
19421943

1943-
mutex_lock(&adapter->rwi_lock);
1944+
spin_lock_irqsave(&adapter->rwi_lock, flags);
19441945

19451946
if (!list_empty(&adapter->rwi_list)) {
19461947
rwi = list_first_entry(&adapter->rwi_list, struct ibmvnic_rwi,
@@ -1950,7 +1951,7 @@ static struct ibmvnic_rwi *get_next_rwi(struct ibmvnic_adapter *adapter)
19501951
rwi = NULL;
19511952
}
19521953

1953-
mutex_unlock(&adapter->rwi_lock);
1954+
spin_unlock_irqrestore(&adapter->rwi_lock, flags);
19541955
return rwi;
19551956
}
19561957

@@ -2025,6 +2026,7 @@ static int ibmvnic_reset(struct ibmvnic_adapter *adapter,
20252026
struct list_head *entry, *tmp_entry;
20262027
struct ibmvnic_rwi *rwi, *tmp;
20272028
struct net_device *netdev = adapter->netdev;
2029+
unsigned long flags;
20282030
int ret;
20292031

20302032
if (adapter->state == VNIC_REMOVING ||
@@ -2041,21 +2043,21 @@ static int ibmvnic_reset(struct ibmvnic_adapter *adapter,
20412043
goto err;
20422044
}
20432045

2044-
mutex_lock(&adapter->rwi_lock);
2046+
spin_lock_irqsave(&adapter->rwi_lock, flags);
20452047

20462048
list_for_each(entry, &adapter->rwi_list) {
20472049
tmp = list_entry(entry, struct ibmvnic_rwi, list);
20482050
if (tmp->reset_reason == reason) {
20492051
netdev_dbg(netdev, "Skipping matching reset\n");
2050-
mutex_unlock(&adapter->rwi_lock);
2052+
spin_unlock_irqrestore(&adapter->rwi_lock, flags);
20512053
ret = EBUSY;
20522054
goto err;
20532055
}
20542056
}
20552057

20562058
rwi = kzalloc(sizeof(*rwi), GFP_KERNEL);
20572059
if (!rwi) {
2058-
mutex_unlock(&adapter->rwi_lock);
2060+
spin_unlock_irqrestore(&adapter->rwi_lock, flags);
20592061
ibmvnic_close(netdev);
20602062
ret = ENOMEM;
20612063
goto err;
@@ -2069,7 +2071,7 @@ static int ibmvnic_reset(struct ibmvnic_adapter *adapter,
20692071
}
20702072
rwi->reset_reason = reason;
20712073
list_add_tail(&rwi->list, &adapter->rwi_list);
2072-
mutex_unlock(&adapter->rwi_lock);
2074+
spin_unlock_irqrestore(&adapter->rwi_lock, flags);
20732075
adapter->resetting = true;
20742076
netdev_dbg(adapter->netdev, "Scheduling reset (reason %d)\n", reason);
20752077
schedule_work(&adapter->ibmvnic_reset);
@@ -4759,7 +4761,7 @@ static int ibmvnic_probe(struct vio_dev *dev, const struct vio_device_id *id)
47594761

47604762
INIT_WORK(&adapter->ibmvnic_reset, __ibmvnic_reset);
47614763
INIT_LIST_HEAD(&adapter->rwi_list);
4762-
mutex_init(&adapter->rwi_lock);
4764+
spin_lock_init(&adapter->rwi_lock);
47634765
adapter->resetting = false;
47644766

47654767
adapter->mac_change_pending = false;

drivers/net/ethernet/ibm/ibmvnic.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1075,7 +1075,7 @@ struct ibmvnic_adapter {
10751075
struct tasklet_struct tasklet;
10761076
enum vnic_state state;
10771077
enum ibmvnic_reset_reason reset_reason;
1078-
struct mutex rwi_lock;
1078+
spinlock_t rwi_lock;
10791079
struct list_head rwi_list;
10801080
struct work_struct ibmvnic_reset;
10811081
bool resetting;

0 commit comments

Comments
 (0)