Skip to content

Commit 6cbe721

Browse files
committed
Merge branch 'ibmvnic-Fix-reset-work-item-locking-bugs'
Thomas Falcon says: ==================== net/ibmvnic: Fix reset work item locking bugs This patch set fixes issues with scheduling reset work items in a tasklet context. Since ibmvnic_reset can called in an interrupt, it should not use a mutex or allocate memory non-atomically. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 5648451 + 1d1bbc3 commit 6cbe721

File tree

2 files changed

+11
-9
lines changed

2 files changed

+11
-9
lines changed

drivers/net/ethernet/ibm/ibmvnic.c

Lines changed: 10 additions & 8 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

2056-
rwi = kzalloc(sizeof(*rwi), GFP_KERNEL);
2058+
rwi = kzalloc(sizeof(*rwi), GFP_ATOMIC);
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)