Skip to content

Commit ae03034

Browse files
Dave MarquardtNipaLocal
authored andcommitted
net: ibmveth: make veth_pool_store stop hanging
Use rtnl_mutex to synchronize veth_pool_store with itself, ibmveth_close and ibmveth_open, preventing multiple calls in a row to napi_disable. Signed-off-by: Dave Marquardt <[email protected]> Fixes: 860f242 ("[PATCH] ibmveth change buffer pools dynamically") Reviewed-by: Nick Child <[email protected]> Signed-off-by: NipaLocal <nipa@local>
1 parent cdbafe6 commit ae03034

File tree

1 file changed

+23
-4
lines changed

1 file changed

+23
-4
lines changed

drivers/net/ethernet/ibm/ibmveth.c

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1802,18 +1802,24 @@ static ssize_t veth_pool_store(struct kobject *kobj, struct attribute *attr,
18021802
long value = simple_strtol(buf, NULL, 10);
18031803
long rc;
18041804

1805+
rtnl_lock();
1806+
18051807
if (attr == &veth_active_attr) {
18061808
if (value && !pool->active) {
18071809
if (netif_running(netdev)) {
18081810
if (ibmveth_alloc_buffer_pool(pool)) {
18091811
netdev_err(netdev,
18101812
"unable to alloc pool\n");
1813+
rtnl_unlock();
18111814
return -ENOMEM;
18121815
}
18131816
pool->active = 1;
18141817
ibmveth_close(netdev);
1815-
if ((rc = ibmveth_open(netdev)))
1818+
rc = ibmveth_open(netdev);
1819+
if (rc) {
1820+
rtnl_unlock();
18161821
return rc;
1822+
}
18171823
} else {
18181824
pool->active = 1;
18191825
}
@@ -1833,44 +1839,57 @@ static ssize_t veth_pool_store(struct kobject *kobj, struct attribute *attr,
18331839

18341840
if (i == IBMVETH_NUM_BUFF_POOLS) {
18351841
netdev_err(netdev, "no active pool >= MTU\n");
1842+
rtnl_unlock();
18361843
return -EPERM;
18371844
}
18381845

18391846
if (netif_running(netdev)) {
18401847
ibmveth_close(netdev);
18411848
pool->active = 0;
1842-
if ((rc = ibmveth_open(netdev)))
1849+
rc = ibmveth_open(netdev);
1850+
if (rc) {
1851+
rtnl_unlock();
18431852
return rc;
1853+
}
18441854
}
18451855
pool->active = 0;
18461856
}
18471857
} else if (attr == &veth_num_attr) {
18481858
if (value <= 0 || value > IBMVETH_MAX_POOL_COUNT) {
1859+
rtnl_unlock();
18491860
return -EINVAL;
18501861
} else {
18511862
if (netif_running(netdev)) {
18521863
ibmveth_close(netdev);
18531864
pool->size = value;
1854-
if ((rc = ibmveth_open(netdev)))
1865+
rc = ibmveth_open(netdev);
1866+
if (rc) {
1867+
rtnl_unlock();
18551868
return rc;
1869+
}
18561870
} else {
18571871
pool->size = value;
18581872
}
18591873
}
18601874
} else if (attr == &veth_size_attr) {
18611875
if (value <= IBMVETH_BUFF_OH || value > IBMVETH_MAX_BUF_SIZE) {
1876+
rtnl_unlock();
18621877
return -EINVAL;
18631878
} else {
18641879
if (netif_running(netdev)) {
18651880
ibmveth_close(netdev);
18661881
pool->buff_size = value;
1867-
if ((rc = ibmveth_open(netdev)))
1882+
rc = ibmveth_open(netdev);
1883+
if (rc) {
1884+
rtnl_unlock();
18681885
return rc;
1886+
}
18691887
} else {
18701888
pool->buff_size = value;
18711889
}
18721890
}
18731891
}
1892+
rtnl_unlock();
18741893

18751894
/* kick the interrupt handler to allocate/deallocate pools */
18761895
ibmveth_interrupt(netdev->irq, netdev);

0 commit comments

Comments
 (0)