Skip to content

Commit 1fb9fed

Browse files
mmarcinirolandd
authored andcommitted
IB/qib: Fix QP RCU sparse warnings
Commit af061a6 ("IB/qib: Use RCU for qpn lookup") introduced sparse warnings. This patch corrects those issues. Signed-off-by: Mike Marciniszyn <mike.marciniszyn@intel.com> Signed-off-by: Roland Dreier <roland@purestorage.com>
1 parent 7e23017 commit 1fb9fed

File tree

5 files changed

+61
-35
lines changed

5 files changed

+61
-35
lines changed

drivers/infiniband/hw/qib/qib_iba7322.c

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/*
2-
* Copyright (c) 2008, 2009, 2010 QLogic Corporation. All rights reserved.
2+
* Copyright (c) 2012 Intel Corporation. All rights reserved.
3+
* Copyright (c) 2008 - 2012 QLogic Corporation. All rights reserved.
34
*
45
* This software is available to you under a choice of one of two
56
* licenses. You may choose to be licensed under the terms of the GNU
@@ -49,6 +50,7 @@
4950
#include "qib_qsfp.h"
5051

5152
#include "qib_mad.h"
53+
#include "qib_verbs.h"
5254

5355
static void qib_setup_7322_setextled(struct qib_pportdata *, u32);
5456
static void qib_7322_handle_hwerrors(struct qib_devdata *, char *, size_t);
@@ -5151,15 +5153,11 @@ static void try_7322_ipg(struct qib_pportdata *ppd)
51515153
goto retry;
51525154

51535155
if (!ibp->smi_ah) {
5154-
struct ib_ah_attr attr;
51555156
struct ib_ah *ah;
51565157

5157-
memset(&attr, 0, sizeof attr);
5158-
attr.dlid = be16_to_cpu(IB_LID_PERMISSIVE);
5159-
attr.port_num = ppd->port;
5160-
ah = ib_create_ah(ibp->qp0->ibqp.pd, &attr);
5158+
ah = qib_create_qp0_ah(ibp, be16_to_cpu(IB_LID_PERMISSIVE));
51615159
if (IS_ERR(ah))
5162-
ret = -EINVAL;
5160+
ret = PTR_ERR(ah);
51635161
else {
51645162
send_buf->ah = ah;
51655163
ibp->smi_ah = to_iah(ah);

drivers/infiniband/hw/qib/qib_mad.c

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
2-
* Copyright (c) 2006, 2007, 2008, 2009, 2010 QLogic Corporation.
3-
* All rights reserved.
2+
* Copyright (c) 2012 Intel Corporation. All rights reserved.
3+
* Copyright (c) 2006 - 2012 QLogic Corporation. All rights reserved.
44
* Copyright (c) 2005, 2006 PathScale, Inc. All rights reserved.
55
*
66
* This software is available to you under a choice of one of two
@@ -90,14 +90,10 @@ static void qib_send_trap(struct qib_ibport *ibp, void *data, unsigned len)
9090
if (!ibp->sm_ah) {
9191
if (ibp->sm_lid != be16_to_cpu(IB_LID_PERMISSIVE)) {
9292
struct ib_ah *ah;
93-
struct ib_ah_attr attr;
9493

95-
memset(&attr, 0, sizeof attr);
96-
attr.dlid = ibp->sm_lid;
97-
attr.port_num = ppd_from_ibp(ibp)->port;
98-
ah = ib_create_ah(ibp->qp0->ibqp.pd, &attr);
94+
ah = qib_create_qp0_ah(ibp, ibp->sm_lid);
9995
if (IS_ERR(ah))
100-
ret = -EINVAL;
96+
ret = PTR_ERR(ah);
10197
else {
10298
send_buf->ah = ah;
10399
ibp->sm_ah = to_iah(ah);

drivers/infiniband/hw/qib/qib_qp.c

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
2-
* Copyright (c) 2006, 2007, 2008, 2009, 2010 QLogic Corporation.
3-
* All rights reserved.
2+
* Copyright (c) 2012 Intel Corporation. All rights reserved.
3+
* Copyright (c) 2006 - 2012 QLogic Corporation. * All rights reserved.
44
* Copyright (c) 2005, 2006 PathScale, Inc. All rights reserved.
55
*
66
* This software is available to you under a choice of one of two
@@ -250,23 +250,33 @@ static void remove_qp(struct qib_ibdev *dev, struct qib_qp *qp)
250250

251251
spin_lock_irqsave(&dev->qpt_lock, flags);
252252

253-
if (ibp->qp0 == qp) {
253+
if (rcu_dereference_protected(ibp->qp0,
254+
lockdep_is_held(&dev->qpt_lock)) == qp) {
254255
atomic_dec(&qp->refcount);
255256
rcu_assign_pointer(ibp->qp0, NULL);
256-
} else if (ibp->qp1 == qp) {
257+
} else if (rcu_dereference_protected(ibp->qp1,
258+
lockdep_is_held(&dev->qpt_lock)) == qp) {
257259
atomic_dec(&qp->refcount);
258260
rcu_assign_pointer(ibp->qp1, NULL);
259261
} else {
260-
struct qib_qp *q, **qpp;
262+
struct qib_qp *q;
263+
struct qib_qp __rcu **qpp;
261264

262265
qpp = &dev->qp_table[n];
263-
for (; (q = *qpp) != NULL; qpp = &q->next)
266+
q = rcu_dereference_protected(*qpp,
267+
lockdep_is_held(&dev->qpt_lock));
268+
for (; q; qpp = &q->next) {
264269
if (q == qp) {
265270
atomic_dec(&qp->refcount);
266-
rcu_assign_pointer(*qpp, qp->next);
267-
qp->next = NULL;
271+
*qpp = qp->next;
272+
rcu_assign_pointer(qp->next, NULL);
273+
q = rcu_dereference_protected(*qpp,
274+
lockdep_is_held(&dev->qpt_lock));
268275
break;
269276
}
277+
q = rcu_dereference_protected(*qpp,
278+
lockdep_is_held(&dev->qpt_lock));
279+
}
270280
}
271281

272282
spin_unlock_irqrestore(&dev->qpt_lock, flags);
@@ -302,10 +312,12 @@ unsigned qib_free_all_qps(struct qib_devdata *dd)
302312

303313
spin_lock_irqsave(&dev->qpt_lock, flags);
304314
for (n = 0; n < dev->qp_table_size; n++) {
305-
qp = dev->qp_table[n];
315+
qp = rcu_dereference_protected(dev->qp_table[n],
316+
lockdep_is_held(&dev->qpt_lock));
306317
rcu_assign_pointer(dev->qp_table[n], NULL);
307318

308-
for (; qp; qp = qp->next)
319+
for (; qp; qp = rcu_dereference_protected(qp->next,
320+
lockdep_is_held(&dev->qpt_lock)))
309321
qp_inuse++;
310322
}
311323
spin_unlock_irqrestore(&dev->qpt_lock, flags);
@@ -337,7 +349,8 @@ struct qib_qp *qib_lookup_qpn(struct qib_ibport *ibp, u32 qpn)
337349
unsigned n = qpn_hash(dev, qpn);
338350

339351
rcu_read_lock();
340-
for (qp = dev->qp_table[n]; rcu_dereference(qp); qp = qp->next)
352+
for (qp = rcu_dereference(dev->qp_table[n]); qp;
353+
qp = rcu_dereference(qp->next))
341354
if (qp->ibqp.qp_num == qpn)
342355
break;
343356
}

drivers/infiniband/hw/qib/qib_verbs.c

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
2-
* Copyright (c) 2006, 2007, 2008, 2009, 2010 QLogic Corporation.
3-
* All rights reserved.
2+
* Copyright (c) 2012 Intel Corporation. All rights reserved.
3+
* Copyright (c) 2006 - 2012 QLogic Corporation. All rights reserved.
44
* Copyright (c) 2005, 2006 PathScale, Inc. All rights reserved.
55
*
66
* This software is available to you under a choice of one of two
@@ -1845,6 +1845,23 @@ static struct ib_ah *qib_create_ah(struct ib_pd *pd,
18451845
return ret;
18461846
}
18471847

1848+
struct ib_ah *qib_create_qp0_ah(struct qib_ibport *ibp, u16 dlid)
1849+
{
1850+
struct ib_ah_attr attr;
1851+
struct ib_ah *ah = ERR_PTR(-EINVAL);
1852+
struct qib_qp *qp0;
1853+
1854+
memset(&attr, 0, sizeof attr);
1855+
attr.dlid = dlid;
1856+
attr.port_num = ppd_from_ibp(ibp)->port;
1857+
rcu_read_lock();
1858+
qp0 = rcu_dereference(ibp->qp0);
1859+
if (qp0)
1860+
ah = ib_create_ah(qp0->ibqp.pd, &attr);
1861+
rcu_read_unlock();
1862+
return ah;
1863+
}
1864+
18481865
/**
18491866
* qib_destroy_ah - destroy an address handle
18501867
* @ibah: the AH to destroy
@@ -2060,7 +2077,7 @@ int qib_register_ib_device(struct qib_devdata *dd)
20602077
spin_lock_init(&dev->lk_table.lock);
20612078
dev->lk_table.max = 1 << ib_qib_lkey_table_size;
20622079
lk_tab_size = dev->lk_table.max * sizeof(*dev->lk_table.table);
2063-
dev->lk_table.table = (struct qib_mregion **)
2080+
dev->lk_table.table = (struct qib_mregion __rcu **)
20642081
__get_free_pages(GFP_KERNEL, get_order(lk_tab_size));
20652082
if (dev->lk_table.table == NULL) {
20662083
ret = -ENOMEM;

drivers/infiniband/hw/qib/qib_verbs.h

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
2-
* Copyright (c) 2006, 2007, 2008, 2009, 2010 QLogic Corporation.
3-
* All rights reserved.
2+
* Copyright (c) 2012 Intel Corporation. All rights reserved.
3+
* Copyright (c) 2006 - 2012 QLogic Corporation. All rights reserved.
44
* Copyright (c) 2005, 2006 PathScale, Inc. All rights reserved.
55
*
66
* This software is available to you under a choice of one of two
@@ -420,7 +420,7 @@ struct qib_qp {
420420
/* read mostly fields above and below */
421421
struct ib_ah_attr remote_ah_attr;
422422
struct ib_ah_attr alt_ah_attr;
423-
struct qib_qp *next; /* link list for QPN hash table */
423+
struct qib_qp __rcu *next; /* link list for QPN hash table */
424424
struct qib_swqe *s_wq; /* send work queue */
425425
struct qib_mmap_info *ip;
426426
struct qib_ib_header *s_hdr; /* next packet header to send */
@@ -659,8 +659,8 @@ struct qib_opcode_stats {
659659
};
660660

661661
struct qib_ibport {
662-
struct qib_qp *qp0;
663-
struct qib_qp *qp1;
662+
struct qib_qp __rcu *qp0;
663+
struct qib_qp __rcu *qp1;
664664
struct ib_mad_agent *send_agent; /* agent for SMI (traps) */
665665
struct qib_ah *sm_ah;
666666
struct qib_ah *smi_ah;
@@ -743,7 +743,7 @@ struct qib_ibdev {
743743
struct list_head memwait; /* list for wait kernel memory */
744744
struct list_head txreq_free;
745745
struct timer_list mem_timer;
746-
struct qib_qp **qp_table;
746+
struct qib_qp __rcu **qp_table;
747747
struct qib_pio_header *pio_hdrs;
748748
dma_addr_t pio_hdrs_phys;
749749
/* list of QPs waiting for RNR timer */
@@ -937,6 +937,8 @@ void qib_rc_rcv(struct qib_ctxtdata *rcd, struct qib_ib_header *hdr,
937937

938938
int qib_check_ah(struct ib_device *ibdev, struct ib_ah_attr *ah_attr);
939939

940+
struct ib_ah *qib_create_qp0_ah(struct qib_ibport *ibp, u16 dlid);
941+
940942
void qib_rc_rnr_retry(unsigned long arg);
941943

942944
void qib_rc_send_complete(struct qib_qp *qp, struct qib_ib_header *hdr);

0 commit comments

Comments
 (0)