]>
Commit | Line | Data |
---|---|---|
91d8a35c DM |
1 | From fa16ebed31f336e41970f3f0ea9e8279f6be2d27 Mon Sep 17 00:00:00 2001 |
2 | From: Shlomo Pongratz <shlomop@mellanox.com> | |
3 | Date: Mon, 13 Aug 2012 14:39:49 +0000 | |
4 | Subject: IB/ipoib: Add missing locking when CM object is deleted | |
5 | ||
6 | Commit b63b70d87741 ("IPoIB: Use a private hash table for path lookup | |
7 | in xmit path") introduced a bug where in ipoib_cm_destroy_tx() a CM | |
8 | object is moved between lists without any supported locking. Under a | |
9 | stress test, this eventually leads to list corruption and a crash. | |
10 | ||
11 | Previously when this routine was called, callers were taking the | |
12 | device priv lock. Currently this function is called from the RCU | |
13 | callback associated with neighbour deletion. Fix the race by taking | |
14 | the same lock we used to before. | |
15 | ||
16 | Signed-off-by: Shlomo Pongratz <shlomop@mellanox.com> | |
17 | Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com> | |
18 | Signed-off-by: Roland Dreier <roland@purestorage.com> | |
19 | --- | |
20 | diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c | |
21 | index 95ecf4e..24683fd 100644 | |
22 | --- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c | |
23 | +++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c | |
24 | @@ -1271,12 +1271,15 @@ struct ipoib_cm_tx *ipoib_cm_create_tx(struct net_device *dev, struct ipoib_path | |
25 | void ipoib_cm_destroy_tx(struct ipoib_cm_tx *tx) | |
26 | { | |
27 | struct ipoib_dev_priv *priv = netdev_priv(tx->dev); | |
28 | + unsigned long flags; | |
29 | if (test_and_clear_bit(IPOIB_FLAG_INITIALIZED, &tx->flags)) { | |
30 | + spin_lock_irqsave(&priv->lock, flags); | |
31 | list_move(&tx->list, &priv->cm.reap_list); | |
32 | queue_work(ipoib_workqueue, &priv->cm.reap_task); | |
33 | ipoib_dbg(priv, "Reap connection for gid %pI6\n", | |
34 | tx->neigh->daddr + 4); | |
35 | tx->neigh = NULL; | |
36 | + spin_unlock_irqrestore(&priv->lock, flags); | |
37 | } | |
38 | } | |
39 | ||
40 | -- | |
41 | cgit v0.9.1 |