Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1fb9fed6 authored by Mike Marciniszyn's avatar Mike Marciniszyn Committed by Roland Dreier
Browse files

IB/qib: Fix QP RCU sparse warnings



Commit af061a64 ("IB/qib: Use RCU for qpn lookup") introduced sparse
warnings.

This patch corrects those issues.

Signed-off-by: default avatarMike Marciniszyn <mike.marciniszyn@intel.com>
Signed-off-by: default avatarRoland Dreier <roland@purestorage.com>
parent 7e230177
Loading
Loading
Loading
Loading
+5 −7
Original line number Original line Diff line number Diff line
/*
/*
 * Copyright (c) 2008, 2009, 2010 QLogic Corporation. All rights reserved.
 * Copyright (c) 2012 Intel Corporation.  All rights reserved.
 * Copyright (c) 2008 - 2012 QLogic Corporation. All rights reserved.
 *
 *
 * This software is available to you under a choice of one of two
 * This software is available to you under a choice of one of two
 * licenses.  You may choose to be licensed under the terms of the GNU
 * licenses.  You may choose to be licensed under the terms of the GNU
@@ -49,6 +50,7 @@
#include "qib_qsfp.h"
#include "qib_qsfp.h"


#include "qib_mad.h"
#include "qib_mad.h"
#include "qib_verbs.h"


static void qib_setup_7322_setextled(struct qib_pportdata *, u32);
static void qib_setup_7322_setextled(struct qib_pportdata *, u32);
static void qib_7322_handle_hwerrors(struct qib_devdata *, char *, size_t);
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)
		goto retry;
		goto retry;


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


		memset(&attr, 0, sizeof attr);
		ah = qib_create_qp0_ah(ibp, be16_to_cpu(IB_LID_PERMISSIVE));
		attr.dlid = be16_to_cpu(IB_LID_PERMISSIVE);
		attr.port_num = ppd->port;
		ah = ib_create_ah(ibp->qp0->ibqp.pd, &attr);
		if (IS_ERR(ah))
		if (IS_ERR(ah))
			ret = -EINVAL;
			ret = PTR_ERR(ah);
		else {
		else {
			send_buf->ah = ah;
			send_buf->ah = ah;
			ibp->smi_ah = to_iah(ah);
			ibp->smi_ah = to_iah(ah);
+4 −8
Original line number Original line Diff line number Diff line
/*
/*
 * Copyright (c) 2006, 2007, 2008, 2009, 2010 QLogic Corporation.
 * Copyright (c) 2012 Intel Corporation.  All rights reserved.
 * All rights reserved.
 * Copyright (c) 2006 - 2012 QLogic Corporation. All rights reserved.
 * Copyright (c) 2005, 2006 PathScale, Inc. All rights reserved.
 * Copyright (c) 2005, 2006 PathScale, Inc. All rights reserved.
 *
 *
 * This software is available to you under a choice of one of two
 * 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)
	if (!ibp->sm_ah) {
	if (!ibp->sm_ah) {
		if (ibp->sm_lid != be16_to_cpu(IB_LID_PERMISSIVE)) {
		if (ibp->sm_lid != be16_to_cpu(IB_LID_PERMISSIVE)) {
			struct ib_ah *ah;
			struct ib_ah *ah;
			struct ib_ah_attr attr;


			memset(&attr, 0, sizeof attr);
			ah = qib_create_qp0_ah(ibp, ibp->sm_lid);
			attr.dlid = ibp->sm_lid;
			attr.port_num = ppd_from_ibp(ibp)->port;
			ah = ib_create_ah(ibp->qp0->ibqp.pd, &attr);
			if (IS_ERR(ah))
			if (IS_ERR(ah))
				ret = -EINVAL;
				ret = PTR_ERR(ah);
			else {
			else {
				send_buf->ah = ah;
				send_buf->ah = ah;
				ibp->sm_ah = to_iah(ah);
				ibp->sm_ah = to_iah(ah);
+24 −11
Original line number Original line Diff line number Diff line
/*
/*
 * Copyright (c) 2006, 2007, 2008, 2009, 2010 QLogic Corporation.
 * Copyright (c) 2012 Intel Corporation.  All rights reserved.
 * All rights reserved.
 * Copyright (c) 2006 - 2012 QLogic Corporation.  * All rights reserved.
 * Copyright (c) 2005, 2006 PathScale, Inc. All rights reserved.
 * Copyright (c) 2005, 2006 PathScale, Inc. All rights reserved.
 *
 *
 * This software is available to you under a choice of one of two
 * 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)


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


	if (ibp->qp0 == qp) {
	if (rcu_dereference_protected(ibp->qp0,
			lockdep_is_held(&dev->qpt_lock)) == qp) {
		atomic_dec(&qp->refcount);
		atomic_dec(&qp->refcount);
		rcu_assign_pointer(ibp->qp0, NULL);
		rcu_assign_pointer(ibp->qp0, NULL);
	} else if (ibp->qp1 == qp) {
	} else if (rcu_dereference_protected(ibp->qp1,
			lockdep_is_held(&dev->qpt_lock)) == qp) {
		atomic_dec(&qp->refcount);
		atomic_dec(&qp->refcount);
		rcu_assign_pointer(ibp->qp1, NULL);
		rcu_assign_pointer(ibp->qp1, NULL);
	} else {
	} else {
		struct qib_qp *q, **qpp;
		struct qib_qp *q;
		struct qib_qp __rcu **qpp;


		qpp = &dev->qp_table[n];
		qpp = &dev->qp_table[n];
		for (; (q = *qpp) != NULL; qpp = &q->next)
		q = rcu_dereference_protected(*qpp,
			lockdep_is_held(&dev->qpt_lock));
		for (; q; qpp = &q->next) {
			if (q == qp) {
			if (q == qp) {
				atomic_dec(&qp->refcount);
				atomic_dec(&qp->refcount);
				rcu_assign_pointer(*qpp, qp->next);
				*qpp = qp->next;
				qp->next = NULL;
				rcu_assign_pointer(qp->next, NULL);
				q = rcu_dereference_protected(*qpp,
					lockdep_is_held(&dev->qpt_lock));
				break;
				break;
			}
			}
			q = rcu_dereference_protected(*qpp,
				lockdep_is_held(&dev->qpt_lock));
		}
	}
	}


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


	spin_lock_irqsave(&dev->qpt_lock, flags);
	spin_lock_irqsave(&dev->qpt_lock, flags);
	for (n = 0; n < dev->qp_table_size; n++) {
	for (n = 0; n < dev->qp_table_size; n++) {
		qp = dev->qp_table[n];
		qp = rcu_dereference_protected(dev->qp_table[n],
			lockdep_is_held(&dev->qpt_lock));
		rcu_assign_pointer(dev->qp_table[n], NULL);
		rcu_assign_pointer(dev->qp_table[n], NULL);


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


		rcu_read_lock();
		rcu_read_lock();
		for (qp = dev->qp_table[n]; rcu_dereference(qp); qp = qp->next)
		for (qp = rcu_dereference(dev->qp_table[n]); qp;
			qp = rcu_dereference(qp->next))
			if (qp->ibqp.qp_num == qpn)
			if (qp->ibqp.qp_num == qpn)
				break;
				break;
	}
	}
+20 −3
Original line number Original line Diff line number Diff line
/*
/*
 * Copyright (c) 2006, 2007, 2008, 2009, 2010 QLogic Corporation.
 * Copyright (c) 2012 Intel Corporation.  All rights reserved.
 * All rights reserved.
 * Copyright (c) 2006 - 2012 QLogic Corporation. All rights reserved.
 * Copyright (c) 2005, 2006 PathScale, Inc. All rights reserved.
 * Copyright (c) 2005, 2006 PathScale, Inc. All rights reserved.
 *
 *
 * This software is available to you under a choice of one of two
 * 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,
	return ret;
	return ret;
}
}


struct ib_ah *qib_create_qp0_ah(struct qib_ibport *ibp, u16 dlid)
{
	struct ib_ah_attr attr;
	struct ib_ah *ah = ERR_PTR(-EINVAL);
	struct qib_qp *qp0;

	memset(&attr, 0, sizeof attr);
	attr.dlid = dlid;
	attr.port_num = ppd_from_ibp(ibp)->port;
	rcu_read_lock();
	qp0 = rcu_dereference(ibp->qp0);
	if (qp0)
		ah = ib_create_ah(qp0->ibqp.pd, &attr);
	rcu_read_unlock();
	return ah;
}

/**
/**
 * qib_destroy_ah - destroy an address handle
 * qib_destroy_ah - destroy an address handle
 * @ibah: the AH to destroy
 * @ibah: the AH to destroy
@@ -2060,7 +2077,7 @@ int qib_register_ib_device(struct qib_devdata *dd)
	spin_lock_init(&dev->lk_table.lock);
	spin_lock_init(&dev->lk_table.lock);
	dev->lk_table.max = 1 << ib_qib_lkey_table_size;
	dev->lk_table.max = 1 << ib_qib_lkey_table_size;
	lk_tab_size = dev->lk_table.max * sizeof(*dev->lk_table.table);
	lk_tab_size = dev->lk_table.max * sizeof(*dev->lk_table.table);
	dev->lk_table.table = (struct qib_mregion **)
	dev->lk_table.table = (struct qib_mregion __rcu **)
		__get_free_pages(GFP_KERNEL, get_order(lk_tab_size));
		__get_free_pages(GFP_KERNEL, get_order(lk_tab_size));
	if (dev->lk_table.table == NULL) {
	if (dev->lk_table.table == NULL) {
		ret = -ENOMEM;
		ret = -ENOMEM;
+8 −6
Original line number Original line Diff line number Diff line
/*
/*
 * Copyright (c) 2006, 2007, 2008, 2009, 2010 QLogic Corporation.
 * Copyright (c) 2012 Intel Corporation.  All rights reserved.
 * All rights reserved.
 * Copyright (c) 2006 - 2012 QLogic Corporation. All rights reserved.
 * Copyright (c) 2005, 2006 PathScale, Inc. All rights reserved.
 * Copyright (c) 2005, 2006 PathScale, Inc. All rights reserved.
 *
 *
 * This software is available to you under a choice of one of two
 * This software is available to you under a choice of one of two
@@ -420,7 +420,7 @@ struct qib_qp {
	/* read mostly fields above and below */
	/* read mostly fields above and below */
	struct ib_ah_attr remote_ah_attr;
	struct ib_ah_attr remote_ah_attr;
	struct ib_ah_attr alt_ah_attr;
	struct ib_ah_attr alt_ah_attr;
	struct qib_qp *next;            /* link list for QPN hash table */
	struct qib_qp __rcu *next;            /* link list for QPN hash table */
	struct qib_swqe *s_wq;  /* send work queue */
	struct qib_swqe *s_wq;  /* send work queue */
	struct qib_mmap_info *ip;
	struct qib_mmap_info *ip;
	struct qib_ib_header *s_hdr;     /* next packet header to send */
	struct qib_ib_header *s_hdr;     /* next packet header to send */
@@ -659,8 +659,8 @@ struct qib_opcode_stats {
};
};


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


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


struct ib_ah *qib_create_qp0_ah(struct qib_ibport *ibp, u16 dlid);

void qib_rc_rnr_retry(unsigned long arg);
void qib_rc_rnr_retry(unsigned long arg);


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