Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 316388
b: refs/heads/master
c: 551ace1
h: refs/heads/master
v: v3
  • Loading branch information
Mike Marciniszyn authored and Roland Dreier committed Jul 19, 2012
1 parent 65d5dda commit fcd491e
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 13 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: f3331f88a4b97530b7acd3112902524d9dc0688c
refs/heads/master: 551ace124d0ef471e8a5fee3ef9e5bb7460251be
10 changes: 8 additions & 2 deletions trunk/drivers/infiniband/hw/qib/qib.h
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#ifndef _QIB_KERNEL_H
#define _QIB_KERNEL_H
/*
* Copyright (c) 2006, 2007, 2008, 2009, 2010 QLogic Corporation.
* All rights reserved.
* Copyright (c) 2012 Intel Corporation. All rights reserved.
* Copyright (c) 2006 - 2012 QLogic Corporation. All rights reserved.
* Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved.
*
* This software is available to you under a choice of one of two
Expand Down Expand Up @@ -544,6 +544,7 @@ struct qib_pportdata {

/* read mostly */
struct qib_sdma_desc *sdma_descq;
struct workqueue_struct *qib_wq;
struct qib_sdma_state sdma_state;
dma_addr_t sdma_descq_phys;
volatile __le64 *sdma_head_dma; /* DMA'ed by chip */
Expand Down Expand Up @@ -1267,6 +1268,11 @@ int qib_sdma_verbs_send(struct qib_pportdata *, struct qib_sge_state *,
/* ppd->sdma_lock should be locked before calling this. */
int qib_sdma_make_progress(struct qib_pportdata *dd);

static inline int qib_sdma_empty(const struct qib_pportdata *ppd)
{
return ppd->sdma_descq_added == ppd->sdma_descq_removed;
}

/* must be called under qib_sdma_lock */
static inline u16 qib_sdma_descq_freecnt(const struct qib_pportdata *ppd)
{
Expand Down
51 changes: 49 additions & 2 deletions trunk/drivers/infiniband/hw/qib/qib_init.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2006, 2007, 2008, 2009, 2010 QLogic Corporation.
* All rights reserved.
* Copyright (c) 2012 Intel Corporation. All rights reserved.
* Copyright (c) 2006 - 2012 QLogic Corporation. All rights reserved.
* Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved.
*
* This software is available to you under a choice of one of two
Expand Down Expand Up @@ -210,6 +210,8 @@ void qib_init_pportdata(struct qib_pportdata *ppd, struct qib_devdata *dd,
init_timer(&ppd->symerr_clear_timer);
ppd->symerr_clear_timer.function = qib_clear_symerror_on_linkup;
ppd->symerr_clear_timer.data = (unsigned long)ppd;

ppd->qib_wq = NULL;
}

static int init_pioavailregs(struct qib_devdata *dd)
Expand Down Expand Up @@ -482,6 +484,42 @@ static void init_piobuf_state(struct qib_devdata *dd)
dd->f_initvl15_bufs(dd);
}

/**
* qib_create_workqueues - create per port workqueues
* @dd: the qlogic_ib device
*/
static int qib_create_workqueues(struct qib_devdata *dd)
{
int pidx;
struct qib_pportdata *ppd;

for (pidx = 0; pidx < dd->num_pports; ++pidx) {
ppd = dd->pport + pidx;
if (!ppd->qib_wq) {
char wq_name[8]; /* 3 + 2 + 1 + 1 + 1 */
snprintf(wq_name, sizeof(wq_name), "qib%d_%d",
dd->unit, pidx);
ppd->qib_wq =
create_singlethread_workqueue(wq_name);
if (!ppd->qib_wq)
goto wq_error;
}
}
return 0;
wq_error:
pr_err(
QIB_DRV_NAME ": create_singlethread_workqueue failed for port %d\n",
pidx + 1);
for (pidx = 0; pidx < dd->num_pports; ++pidx) {
ppd = dd->pport + pidx;
if (ppd->qib_wq) {
destroy_workqueue(ppd->qib_wq);
ppd->qib_wq = NULL;
}
}
return -ENOMEM;
}

/**
* qib_init - do the actual initialization sequence on the chip
* @dd: the qlogic_ib device
Expand Down Expand Up @@ -764,6 +802,11 @@ static void qib_shutdown_device(struct qib_devdata *dd)
* We can't count on interrupts since we are stopping.
*/
dd->f_quiet_serdes(ppd);

if (ppd->qib_wq) {
destroy_workqueue(ppd->qib_wq);
ppd->qib_wq = NULL;
}
}

qib_update_eeprom_log(dd);
Expand Down Expand Up @@ -1249,6 +1292,10 @@ static int __devinit qib_init_one(struct pci_dev *pdev,
if (ret)
goto bail; /* error already printed */

ret = qib_create_workqueues(dd);
if (ret)
goto bail;

/* do the generic initialization */
initfail = qib_init(dd, 0);

Expand Down
29 changes: 26 additions & 3 deletions trunk/drivers/infiniband/hw/qib/qib_verbs.c
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,8 @@ static void qib_copy_from_sge(void *data, struct qib_sge_state *ss, u32 length)
* @qp: the QP to post on
* @wr: the work request to send
*/
static int qib_post_one_send(struct qib_qp *qp, struct ib_send_wr *wr)
static int qib_post_one_send(struct qib_qp *qp, struct ib_send_wr *wr,
int *scheduled)
{
struct qib_swqe *wqe;
u32 next;
Expand Down Expand Up @@ -440,6 +441,12 @@ static int qib_post_one_send(struct qib_qp *qp, struct ib_send_wr *wr)
bail_inval:
ret = -EINVAL;
bail:
if (!ret && !wr->next &&
!qib_sdma_empty(
dd_from_ibdev(qp->ibqp.device)->pport + qp->port_num - 1)) {
qib_schedule_send(qp);
*scheduled = 1;
}
spin_unlock_irqrestore(&qp->s_lock, flags);
return ret;
}
Expand All @@ -457,17 +464,19 @@ static int qib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
{
struct qib_qp *qp = to_iqp(ibqp);
int err = 0;
int scheduled = 0;

for (; wr; wr = wr->next) {
err = qib_post_one_send(qp, wr);
err = qib_post_one_send(qp, wr, &scheduled);
if (err) {
*bad_wr = wr;
goto bail;
}
}

/* Try to do the send work in the caller's context. */
qib_do_send(&qp->s_work);
if (!scheduled)
qib_do_send(&qp->s_work);

bail:
return err;
Expand Down Expand Up @@ -2308,3 +2317,17 @@ void qib_unregister_ib_device(struct qib_devdata *dd)
get_order(lk_tab_size));
kfree(dev->qp_table);
}

/*
* This must be called with s_lock held.
*/
void qib_schedule_send(struct qib_qp *qp)
{
if (qib_send_ok(qp)) {
struct qib_ibport *ibp =
to_iport(qp->ibqp.device, qp->port_num);
struct qib_pportdata *ppd = ppd_from_ibp(ibp);

queue_work(ppd->qib_wq, &qp->s_work);
}
}
7 changes: 2 additions & 5 deletions trunk/drivers/infiniband/hw/qib/qib_verbs.h
Original file line number Diff line number Diff line change
Expand Up @@ -727,6 +727,7 @@ struct qib_ibport {
struct qib_opcode_stats opstats[128];
};


struct qib_ibdev {
struct ib_device ibdev;
struct list_head pending_mmaps;
Expand Down Expand Up @@ -836,11 +837,7 @@ extern struct workqueue_struct *qib_cq_wq;
/*
* This must be called with s_lock held.
*/
static inline void qib_schedule_send(struct qib_qp *qp)
{
if (qib_send_ok(qp))
queue_work(ib_wq, &qp->s_work);
}
void qib_schedule_send(struct qib_qp *qp);

static inline int qib_pkey_ok(u16 pkey1, u16 pkey2)
{
Expand Down

0 comments on commit fcd491e

Please sign in to comment.