Skip to content

Commit 0590784

Browse files
karstengrpiso77
authored andcommitted
net/smc: stop links when their GID is removed
BugLink: https://bugs.launchpad.net/bugs/1929035 With SMC-Rv2 the GID is an IP address that can be deleted from the device. When an IB_EVENT_GID_CHANGE event is provided then iterate over all active links and check if their GID is still defined. Otherwise stop the affected link. Signed-off-by: Karsten Graul <kgraul@linux.ibm.com> Signed-off-by: David S. Miller <davem@davemloft.net> (cherry picked from commit 29397e3) Signed-off-by: Frank Heimes <frank.heimes@canonical.com> Acked-by: Tim Gardner <tim.gardner@canonical.com>
1 parent 1039f6b commit 0590784

File tree

1 file changed

+53
-0
lines changed

1 file changed

+53
-0
lines changed

net/smc/smc_ib.c

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,58 @@ int smc_ib_determine_gid(struct smc_ib_device *smcibdev, u8 ibport,
295295
return -ENODEV;
296296
}
297297

298+
/* check if gid is still defined on smcibdev */
299+
static bool smc_ib_check_link_gid(u8 gid[SMC_GID_SIZE], bool smcrv2,
300+
struct smc_ib_device *smcibdev, u8 ibport)
301+
{
302+
const struct ib_gid_attr *attr;
303+
bool rc = false;
304+
int i;
305+
306+
for (i = 0; !rc && i < smcibdev->pattr[ibport - 1].gid_tbl_len; i++) {
307+
attr = rdma_get_gid_attr(smcibdev->ibdev, ibport, i);
308+
if (IS_ERR(attr))
309+
continue;
310+
311+
rcu_read_lock();
312+
if ((!smcrv2 && attr->gid_type == IB_GID_TYPE_ROCE) ||
313+
(smcrv2 && attr->gid_type == IB_GID_TYPE_ROCE_UDP_ENCAP &&
314+
!(ipv6_addr_type((const struct in6_addr *)&attr->gid)
315+
& IPV6_ADDR_LINKLOCAL)))
316+
if (!memcmp(gid, &attr->gid, SMC_GID_SIZE))
317+
rc = true;
318+
rcu_read_unlock();
319+
rdma_put_gid_attr(attr);
320+
}
321+
return rc;
322+
}
323+
324+
/* check all links if the gid is still defined on smcibdev */
325+
static void smc_ib_gid_check(struct smc_ib_device *smcibdev, u8 ibport)
326+
{
327+
struct smc_link_group *lgr;
328+
int i;
329+
330+
spin_lock_bh(&smc_lgr_list.lock);
331+
list_for_each_entry(lgr, &smc_lgr_list.list, list) {
332+
if (strncmp(smcibdev->pnetid[ibport - 1], lgr->pnet_id,
333+
SMC_MAX_PNETID_LEN))
334+
continue; /* lgr is not affected */
335+
if (list_empty(&lgr->list))
336+
continue;
337+
for (i = 0; i < SMC_LINKS_PER_LGR_MAX; i++) {
338+
if (lgr->lnk[i].state == SMC_LNK_UNUSED ||
339+
lgr->lnk[i].smcibdev != smcibdev)
340+
continue;
341+
if (!smc_ib_check_link_gid(lgr->lnk[i].gid,
342+
lgr->smc_version == SMC_V2,
343+
smcibdev, ibport))
344+
smcr_port_err(smcibdev, ibport);
345+
}
346+
}
347+
spin_unlock_bh(&smc_lgr_list.lock);
348+
}
349+
298350
static int smc_ib_remember_port_attr(struct smc_ib_device *smcibdev, u8 ibport)
299351
{
300352
int rc;
@@ -333,6 +385,7 @@ static void smc_ib_port_event_work(struct work_struct *work)
333385
} else {
334386
clear_bit(port_idx, smcibdev->ports_going_away);
335387
smcr_port_add(smcibdev, port_idx + 1);
388+
smc_ib_gid_check(smcibdev, port_idx + 1);
336389
}
337390
}
338391
}

0 commit comments

Comments
 (0)