Skip to content

Commit d97099f

Browse files
committed
IB{cm, core}: Introduce and use ah_attr copy, move, replace APIs
Introduce AH attribute copy, move and replace APIs to be used by core and provider drivers. In CM code flow when ah attribute might be re-initialized twice while processing incoming request, or initialized once while from path record while sending out CM requests. Therefore use rdma_move_ah_attr API to handle such scenarios instead of memcpy(). Provider drivers keeps a copy ah_attr during the lifetime of the ah. Therefore, use rdma_replace_ah_attr() which conditionally release reference to old ah_attr and holds reference to new attribute whose referrence is released when the AH is freed. Signed-off-by: Parav Pandit <parav@mellanox.com> Signed-off-by: Jason Gunthorpe <jgg@mellanox.com> Signed-off-by: Leon Romanovsky <leonro@mellanox.com>
1 parent 947c99e commit d97099f

File tree

6 files changed

+70
-6
lines changed

6 files changed

+70
-6
lines changed

drivers/infiniband/core/cm.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -474,7 +474,7 @@ static int cm_init_av_for_lap(struct cm_port *port, struct ib_wc *wc,
474474
if (ret)
475475
return ret;
476476

477-
memcpy(&av->ah_attr, &new_ah_attr, sizeof(new_ah_attr));
477+
rdma_move_ah_attr(&av->ah_attr, &new_ah_attr);
478478
return 0;
479479
}
480480

@@ -569,7 +569,7 @@ static int cm_init_av_by_path(struct sa_path_rec *path, struct cm_av *av,
569569
ret = add_cm_id_to_port_list(cm_id_priv, av, port);
570570
if (ret)
571571
return ret;
572-
memcpy(&av->ah_attr, &new_ah_attr, sizeof(new_ah_attr));
572+
rdma_move_ah_attr(&av->ah_attr, &new_ah_attr);
573573
return 0;
574574
}
575575

drivers/infiniband/core/verbs.c

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,60 @@ EXPORT_SYMBOL(ib_dealloc_pd);
326326

327327
/* Address handles */
328328

329+
/**
330+
* rdma_copy_ah_attr - Copy rdma ah attribute from source to destination.
331+
* @dest: Pointer to destination ah_attr. Contents of the destination
332+
* pointer is assumed to be invalid and attribute are overwritten.
333+
* @src: Pointer to source ah_attr.
334+
*/
335+
void rdma_copy_ah_attr(struct rdma_ah_attr *dest,
336+
const struct rdma_ah_attr *src)
337+
{
338+
*dest = *src;
339+
if (dest->grh.sgid_attr)
340+
rdma_hold_gid_attr(dest->grh.sgid_attr);
341+
}
342+
EXPORT_SYMBOL(rdma_copy_ah_attr);
343+
344+
/**
345+
* rdma_replace_ah_attr - Replace valid ah_attr with new new one.
346+
* @old: Pointer to existing ah_attr which needs to be replaced.
347+
* old is assumed to be valid or zero'd
348+
* @new: Pointer to the new ah_attr.
349+
*
350+
* rdma_replace_ah_attr() first releases any reference in the old ah_attr if
351+
* old the ah_attr is valid; after that it copies the new attribute and holds
352+
* the reference to the replaced ah_attr.
353+
*/
354+
void rdma_replace_ah_attr(struct rdma_ah_attr *old,
355+
const struct rdma_ah_attr *new)
356+
{
357+
rdma_destroy_ah_attr(old);
358+
*old = *new;
359+
if (old->grh.sgid_attr)
360+
rdma_hold_gid_attr(old->grh.sgid_attr);
361+
}
362+
EXPORT_SYMBOL(rdma_replace_ah_attr);
363+
364+
/**
365+
* rdma_move_ah_attr - Move ah_attr pointed by source to destination.
366+
* @dest: Pointer to destination ah_attr to copy to.
367+
* dest is assumed to be valid or zero'd
368+
* @src: Pointer to the new ah_attr.
369+
*
370+
* rdma_move_ah_attr() first releases any reference in the destination ah_attr
371+
* if it is valid. This also transfers ownership of internal references from
372+
* src to dest, making src invalid in the process. No new reference of the src
373+
* ah_attr is taken.
374+
*/
375+
void rdma_move_ah_attr(struct rdma_ah_attr *dest, struct rdma_ah_attr *src)
376+
{
377+
rdma_destroy_ah_attr(dest);
378+
*dest = *src;
379+
src->grh.sgid_attr = NULL;
380+
}
381+
EXPORT_SYMBOL(rdma_move_ah_attr);
382+
329383
/*
330384
* Validate that the rdma_ah_attr is valid for the device before passing it
331385
* off to the driver.

drivers/infiniband/hw/qedr/verbs.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2302,7 +2302,7 @@ struct ib_ah *qedr_create_ah(struct ib_pd *ibpd, struct rdma_ah_attr *attr,
23022302
if (!ah)
23032303
return ERR_PTR(-ENOMEM);
23042304

2305-
ah->attr = *attr;
2305+
rdma_copy_ah_attr(&ah->attr, attr);
23062306

23072307
return &ah->ibah;
23082308
}
@@ -2311,6 +2311,7 @@ int qedr_destroy_ah(struct ib_ah *ibah)
23112311
{
23122312
struct qedr_ah *ah = get_qedr_ah(ibah);
23132313

2314+
rdma_destroy_ah_attr(&ah->attr);
23142315
kfree(ah);
23152316
return 0;
23162317
}

drivers/infiniband/sw/rdmavt/ah.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,8 @@ struct ib_ah *rvt_create_ah(struct ib_pd *pd,
120120
dev->n_ahs_allocated++;
121121
spin_unlock_irqrestore(&dev->n_ahs_lock, flags);
122122

123-
ah->attr = *ah_attr;
123+
rdma_copy_ah_attr(&ah->attr, ah_attr);
124+
124125
atomic_set(&ah->refcount, 0);
125126

126127
if (dev->driver_f.notify_new_ah)
@@ -148,6 +149,7 @@ int rvt_destroy_ah(struct ib_ah *ibah)
148149
dev->n_ahs_allocated--;
149150
spin_unlock_irqrestore(&dev->n_ahs_lock, flags);
150151

152+
rdma_destroy_ah_attr(&ah->attr);
151153
kfree(ah);
152154

153155
return 0;

drivers/infiniband/sw/rdmavt/qp.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1336,13 +1336,13 @@ int rvt_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
13361336
qp->qp_access_flags = attr->qp_access_flags;
13371337

13381338
if (attr_mask & IB_QP_AV) {
1339-
qp->remote_ah_attr = attr->ah_attr;
1339+
rdma_replace_ah_attr(&qp->remote_ah_attr, &attr->ah_attr);
13401340
qp->s_srate = rdma_ah_get_static_rate(&attr->ah_attr);
13411341
qp->srate_mbps = ib_rate_to_mbps(qp->s_srate);
13421342
}
13431343

13441344
if (attr_mask & IB_QP_ALT_PATH) {
1345-
qp->alt_ah_attr = attr->alt_ah_attr;
1345+
rdma_replace_ah_attr(&qp->alt_ah_attr, &attr->alt_ah_attr);
13461346
qp->s_alt_pkey_index = attr->alt_pkey_index;
13471347
}
13481348

@@ -1459,6 +1459,8 @@ int rvt_destroy_qp(struct ib_qp *ibqp)
14591459
vfree(qp->s_wq);
14601460
rdi->driver_f.qp_priv_free(rdi, qp);
14611461
kfree(qp->s_ack_queue);
1462+
rdma_destroy_ah_attr(&qp->remote_ah_attr);
1463+
rdma_destroy_ah_attr(&qp->alt_ah_attr);
14621464
kfree(qp);
14631465
return 0;
14641466
}

include/rdma/ib_verbs.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4034,6 +4034,11 @@ void rdma_destroy_ah_attr(struct rdma_ah_attr *ah_attr);
40344034
void rdma_move_grh_sgid_attr(struct rdma_ah_attr *attr, union ib_gid *dgid,
40354035
u32 flow_label, u8 hop_limit, u8 traffic_class,
40364036
const struct ib_gid_attr *sgid_attr);
4037+
void rdma_copy_ah_attr(struct rdma_ah_attr *dest,
4038+
const struct rdma_ah_attr *src);
4039+
void rdma_replace_ah_attr(struct rdma_ah_attr *old,
4040+
const struct rdma_ah_attr *new);
4041+
void rdma_move_ah_attr(struct rdma_ah_attr *dest, struct rdma_ah_attr *src);
40374042

40384043
/**
40394044
* rdma_ah_find_type - Return address handle type.

0 commit comments

Comments
 (0)