From 65c7eddaba33995e013ef3c04718f6dc8fdf2335 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Mon, 28 Nov 2005 21:20:34 -0800 Subject: IPoIB: reinitialize path struct's completion for every query It's possible that IPoIB will issue multiple SA queries for the same path struct. Therefore the struct's completion needs to be initialized for each query rather than only once when the struct is allocated, or else we might not wait long enough for later queries to finish and free the path struct too soon. Signed-off-by: Roland Dreier --- drivers/infiniband/ulp/ipoib/ipoib_main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/infiniband/ulp/ipoib') diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c index 2fa30751f362..cd58b3ddd9c4 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c @@ -428,7 +428,6 @@ static struct ipoib_path *path_rec_create(struct net_device *dev, skb_queue_head_init(&path->queue); INIT_LIST_HEAD(&path->neigh_list); - init_completion(&path->done); memcpy(path->pathrec.dgid.raw, gid->raw, sizeof (union ib_gid)); path->pathrec.sgid = priv->local_gid; @@ -446,6 +445,8 @@ static int path_rec_start(struct net_device *dev, ipoib_dbg(priv, "Start path record lookup for " IPOIB_GID_FMT "\n", IPOIB_GID_ARG(path->pathrec.dgid)); + init_completion(&path->done); + path->query_id = ib_sa_path_rec_get(priv->ca, priv->port, &path->pathrec, -- cgit v1.2.1 From 5872a9fc28e6cd3a4e51479a50970d19a01573b3 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Tue, 29 Nov 2005 10:13:54 -0800 Subject: IPoIB: always set path->query to NULL when query finishes Always set path->query to NULL when the SA path record query completes, rather than only when we don't have an address handle. Signed-off-by: Roland Dreier --- drivers/infiniband/ulp/ipoib/ipoib_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/infiniband/ulp/ipoib') diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c index cd58b3ddd9c4..826d7a73ef84 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c @@ -398,9 +398,9 @@ static void path_rec_completion(int status, while ((skb = __skb_dequeue(&neigh->queue))) __skb_queue_tail(&skqueue, skb); } - } else - path->query = NULL; + } + path->query = NULL; complete(&path->done); spin_unlock_irqrestore(&priv->lock, flags); -- cgit v1.2.1 From de922487890936470660e89f9095aee980637989 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Tue, 29 Nov 2005 10:18:45 -0800 Subject: IPoIB: reinitialize mcast structs' completions for every query Make sure mcast->done is initialized to uncompleted value before we submit a new query, so that it's safe to wait on. Signed-off-by: Michael S. Tsirkin Signed-off-by: Roland Dreier --- drivers/infiniband/ulp/ipoib/ipoib_multicast.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers/infiniband/ulp/ipoib') diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c index c33ed87f9dff..10404e09d1ef 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c @@ -135,8 +135,6 @@ static struct ipoib_mcast *ipoib_mcast_alloc(struct net_device *dev, if (!mcast) return NULL; - init_completion(&mcast->done); - mcast->dev = dev; mcast->created = jiffies; mcast->backoff = 1; @@ -350,6 +348,8 @@ static int ipoib_mcast_sendonly_join(struct ipoib_mcast *mcast) rec.port_gid = priv->local_gid; rec.pkey = cpu_to_be16(priv->pkey); + init_completion(&mcast->done); + ret = ib_sa_mcmember_rec_set(priv->ca, priv->port, &rec, IB_SA_MCMEMBER_REC_MGID | IB_SA_MCMEMBER_REC_PORT_GID | @@ -469,6 +469,8 @@ static void ipoib_mcast_join(struct net_device *dev, struct ipoib_mcast *mcast, rec.traffic_class = priv->broadcast->mcmember.traffic_class; } + init_completion(&mcast->done); + ret = ib_sa_mcmember_rec_set(priv->ca, priv->port, &rec, comp_mask, mcast->backoff * 1000, GFP_ATOMIC, ipoib_mcast_join_complete, -- cgit v1.2.1 From 2e86541ec878de9ec5771600a77f451a80bebfc4 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Tue, 29 Nov 2005 10:25:23 -0800 Subject: IPoIB: don't zero members after we allocate with kzalloc ipoib_mcast_alloc() uses kzalloc(), so there's no need to zero out members of the mcast struct after it's allocated. Signed-off-by: Roland Dreier --- drivers/infiniband/ulp/ipoib/ipoib_multicast.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers/infiniband/ulp/ipoib') diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c index 10404e09d1ef..ef3ee035bbc8 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c @@ -138,15 +138,11 @@ static struct ipoib_mcast *ipoib_mcast_alloc(struct net_device *dev, mcast->dev = dev; mcast->created = jiffies; mcast->backoff = 1; - mcast->logcount = 0; INIT_LIST_HEAD(&mcast->list); INIT_LIST_HEAD(&mcast->neigh_list); skb_queue_head_init(&mcast->pkt_queue); - mcast->ah = NULL; - mcast->query = NULL; - return mcast; } -- cgit v1.2.1 From 4f71055a45a503273c039d80db8ba9b13cb17549 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Tue, 29 Nov 2005 10:53:30 -0800 Subject: IPoIB: protect child list in ipoib_ib_dev_flush race condition: ipoib_ib_dev_flush is accessing child list without locks. Signed-off-by: Michael S. Tsirkin Signed-off-by: Roland Dreier --- drivers/infiniband/ulp/ipoib/ipoib_ib.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/infiniband/ulp/ipoib') diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c index 54ef2fea530f..23885801b6d2 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c @@ -608,9 +608,13 @@ void ipoib_ib_dev_flush(void *_dev) if (test_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags)) ipoib_ib_dev_up(dev); + down(&priv->vlan_mutex); + /* Flush any child interfaces too */ list_for_each_entry(cpriv, &priv->child_intfs, list) ipoib_ib_dev_flush(&cpriv->dev); + + up(&priv->vlan_mutex); } void ipoib_ib_dev_cleanup(struct net_device *dev) -- cgit v1.2.1 From 267ee88ed34c76dc527eeb3d95f9f9558ac99973 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Tue, 29 Nov 2005 10:55:58 -0800 Subject: IPoIB: fix error handling in ipoib_open If ipoib_ib_dev_up() fails after ipoib_ib_dev_open() is called, then ipoib_ib_dev_stop() needs to be called to clean up. Signed-off-by: Roland Dreier --- drivers/infiniband/ulp/ipoib/ipoib_main.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/infiniband/ulp/ipoib') diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c index 826d7a73ef84..475d98fa9e26 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c @@ -94,8 +94,10 @@ int ipoib_open(struct net_device *dev) if (ipoib_ib_dev_open(dev)) return -EINVAL; - if (ipoib_ib_dev_up(dev)) + if (ipoib_ib_dev_up(dev)) { + ipoib_ib_dev_stop(dev); return -EINVAL; + } if (!test_bit(IPOIB_FLAG_SUBINTERFACE, &priv->flags)) { struct ipoib_dev_priv *cpriv; -- cgit v1.2.1