Skip to content

Commit 98aebc5

Browse files
Erez Shitritjgunthorpe
authored andcommitted
IB/ipoib: Update pathrec field if not valid record
In case that the PathRecord is not valid (SM changed its network prefix) ipoib will continue issue PathQuery requests with the same parameters that are in its database, which are no longer valid anymore. Now the driver in that case will re-initialize the record from a valid place (the priv structure keeps the updated values), and a valid request will be issued. Signed-off-by: Erez Shitrit <[email protected]> Reviewed-by: Alex Vesker <[email protected]> Signed-off-by: Leon Romanovsky <[email protected]> Signed-off-by: Jason Gunthorpe <[email protected]>
1 parent 4390008 commit 98aebc5

File tree

1 file changed

+34
-15
lines changed

1 file changed

+34
-15
lines changed

drivers/infiniband/ulp/ipoib/ipoib_main.c

Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -856,6 +856,23 @@ static void path_rec_completion(int status,
856856
}
857857
}
858858

859+
static void init_path_rec(struct ipoib_dev_priv *priv, struct ipoib_path *path,
860+
void *gid)
861+
{
862+
path->dev = priv->dev;
863+
864+
if (rdma_cap_opa_ah(priv->ca, priv->port))
865+
path->pathrec.rec_type = SA_PATH_REC_TYPE_OPA;
866+
else
867+
path->pathrec.rec_type = SA_PATH_REC_TYPE_IB;
868+
869+
memcpy(path->pathrec.dgid.raw, gid, sizeof(union ib_gid));
870+
path->pathrec.sgid = priv->local_gid;
871+
path->pathrec.pkey = cpu_to_be16(priv->pkey);
872+
path->pathrec.numb_path = 1;
873+
path->pathrec.traffic_class = priv->broadcast->mcmember.traffic_class;
874+
}
875+
859876
static struct ipoib_path *path_rec_create(struct net_device *dev, void *gid)
860877
{
861878
struct ipoib_dev_priv *priv = ipoib_priv(dev);
@@ -868,21 +885,11 @@ static struct ipoib_path *path_rec_create(struct net_device *dev, void *gid)
868885
if (!path)
869886
return NULL;
870887

871-
path->dev = dev;
872-
873888
skb_queue_head_init(&path->queue);
874889

875890
INIT_LIST_HEAD(&path->neigh_list);
876891

877-
if (rdma_cap_opa_ah(priv->ca, priv->port))
878-
path->pathrec.rec_type = SA_PATH_REC_TYPE_OPA;
879-
else
880-
path->pathrec.rec_type = SA_PATH_REC_TYPE_IB;
881-
memcpy(path->pathrec.dgid.raw, gid, sizeof (union ib_gid));
882-
path->pathrec.sgid = priv->local_gid;
883-
path->pathrec.pkey = cpu_to_be16(priv->pkey);
884-
path->pathrec.numb_path = 1;
885-
path->pathrec.traffic_class = priv->broadcast->mcmember.traffic_class;
892+
init_path_rec(priv, path, gid);
886893

887894
return path;
888895
}
@@ -1011,6 +1018,10 @@ static void unicast_arp_send(struct sk_buff *skb, struct net_device *dev,
10111018

10121019
spin_lock_irqsave(&priv->lock, flags);
10131020

1021+
/* no broadcast means that all paths are (going to be) not valid */
1022+
if (!priv->broadcast)
1023+
goto drop_and_unlock;
1024+
10141025
path = __path_find(dev, phdr->hwaddr + 4);
10151026
if (!path || !path->valid) {
10161027
int new_path = 0;
@@ -1020,6 +1031,10 @@ static void unicast_arp_send(struct sk_buff *skb, struct net_device *dev,
10201031
new_path = 1;
10211032
}
10221033
if (path) {
1034+
if (!new_path)
1035+
/* make sure there is no changes in the existing path record */
1036+
init_path_rec(priv, path, phdr->hwaddr + 4);
1037+
10231038
if (skb_queue_len(&path->queue) < IPOIB_MAX_PATH_REC_QUEUE) {
10241039
push_pseudo_header(skb, phdr->hwaddr);
10251040
__skb_queue_tail(&path->queue, skb);
@@ -1036,8 +1051,7 @@ static void unicast_arp_send(struct sk_buff *skb, struct net_device *dev,
10361051
} else
10371052
__path_add(dev, path);
10381053
} else {
1039-
++dev->stats.tx_dropped;
1040-
dev_kfree_skb_any(skb);
1054+
goto drop_and_unlock;
10411055
}
10421056

10431057
spin_unlock_irqrestore(&priv->lock, flags);
@@ -1057,11 +1071,16 @@ static void unicast_arp_send(struct sk_buff *skb, struct net_device *dev,
10571071
push_pseudo_header(skb, phdr->hwaddr);
10581072
__skb_queue_tail(&path->queue, skb);
10591073
} else {
1060-
++dev->stats.tx_dropped;
1061-
dev_kfree_skb_any(skb);
1074+
goto drop_and_unlock;
10621075
}
10631076

10641077
spin_unlock_irqrestore(&priv->lock, flags);
1078+
return;
1079+
1080+
drop_and_unlock:
1081+
++dev->stats.tx_dropped;
1082+
dev_kfree_skb_any(skb);
1083+
spin_unlock_irqrestore(&priv->lock, flags);
10651084
}
10661085

10671086
static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev)

0 commit comments

Comments
 (0)