diff options
author | André Fabian Silva Delgado <emulatorman@parabola.nu> | 2016-03-25 03:53:42 -0300 |
---|---|---|
committer | André Fabian Silva Delgado <emulatorman@parabola.nu> | 2016-03-25 03:53:42 -0300 |
commit | 03dd4cb26d967f9588437b0fc9cc0e8353322bb7 (patch) | |
tree | fa581f6dc1c0596391690d1f67eceef3af8246dc /drivers/staging/rdma/hfi1/init.c | |
parent | d4e493caf788ef44982e131ff9c786546904d934 (diff) |
Linux-libre 4.5-gnu
Diffstat (limited to 'drivers/staging/rdma/hfi1/init.c')
-rw-r--r-- | drivers/staging/rdma/hfi1/init.c | 101 |
1 files changed, 74 insertions, 27 deletions
diff --git a/drivers/staging/rdma/hfi1/init.c b/drivers/staging/rdma/hfi1/init.c index 8666f3ad2..4dd8051ab 100644 --- a/drivers/staging/rdma/hfi1/init.c +++ b/drivers/staging/rdma/hfi1/init.c @@ -60,6 +60,7 @@ #include "hfi.h" #include "device.h" #include "common.h" +#include "trace.h" #include "mad.h" #include "sdma.h" #include "debugfs.h" @@ -81,15 +82,15 @@ * Number of user receive contexts we are configured to use (to allow for more * pio buffers per ctxt, etc.) Zero means use one user context per CPU. */ -uint num_rcv_contexts; -module_param_named(num_rcv_contexts, num_rcv_contexts, uint, S_IRUGO); +int num_user_contexts = -1; +module_param_named(num_user_contexts, num_user_contexts, uint, S_IRUGO); MODULE_PARM_DESC( - num_rcv_contexts, "Set max number of user receive contexts to use"); + num_user_contexts, "Set max number of user contexts to use"); u8 krcvqs[RXE_NUM_DATA_VL]; int krcvqsset; module_param_array(krcvqs, byte, &krcvqsset, S_IRUGO); -MODULE_PARM_DESC(krcvqs, "Array of the number of kernel receive queues by VL"); +MODULE_PARM_DESC(krcvqs, "Array of the number of non-control kernel receive queues by VL"); /* computed based on above array */ unsigned n_krcvqs; @@ -112,7 +113,7 @@ MODULE_PARM_DESC(hdrq_entsize, "Size of header queue entries: 2 - 8B, 16 - 64B ( unsigned int user_credit_return_threshold = 33; /* default is 33% */ module_param(user_credit_return_threshold, uint, S_IRUGO); -MODULE_PARM_DESC(user_credit_return_theshold, "Credit return threshold for user send contexts, return when unreturned credits passes this many blocks (in percent of allocated blocks, 0 is off)"); +MODULE_PARM_DESC(user_credit_return_threshold, "Credit return threshold for user send contexts, return when unreturned credits passes this many blocks (in percent of allocated blocks, 0 is off)"); static inline u64 encode_rcv_header_entry_size(u16); @@ -129,6 +130,9 @@ int hfi1_create_ctxts(struct hfi1_devdata *dd) int ret; int local_node_id = pcibus_to_node(dd->pcidev->bus); + /* Control context has to be always 0 */ + BUILD_BUG_ON(HFI1_CTRL_CTXT != 0); + if (local_node_id < 0) local_node_id = numa_node_id(); dd->assigned_node_id = local_node_id; @@ -158,6 +162,10 @@ int hfi1_create_ctxts(struct hfi1_devdata *dd) HFI1_CAP_KGET(NODROP_RHQ_FULL) | HFI1_CAP_KGET(NODROP_EGR_FULL) | HFI1_CAP_KGET(DMA_RTAIL); + + /* Control context must use DMA_RTAIL */ + if (rcd->ctxt == HFI1_CTRL_CTXT) + rcd->flags |= HFI1_CAP_DMA_RTAIL; rcd->seq_cnt = 1; rcd->sc = sc_alloc(dd, SC_ACK, rcd->rcvhdrqentsize, dd->node); @@ -208,7 +216,7 @@ struct hfi1_ctxtdata *hfi1_create_ctxtdata(struct hfi1_pportdata *ppd, u32 ctxt) if (rcd) { u32 rcvtids, max_entries; - dd_dev_info(dd, "%s: setting up context %u\n", __func__, ctxt); + hfi1_cdbg(PROC, "setting up context %u\n", ctxt); INIT_LIST_HEAD(&rcd->qp_wait_list); rcd->ppd = ppd; @@ -279,8 +287,9 @@ struct hfi1_ctxtdata *hfi1_create_ctxtdata(struct hfi1_pportdata *ppd, u32 ctxt) rcd->ctxt); rcd->egrbufs.count = MAX_EAGER_ENTRIES; } - dd_dev_info(dd, "ctxt%u: max Eager buffer RcvArray entries: %u\n", - rcd->ctxt, rcd->egrbufs.count); + hfi1_cdbg(PROC, + "ctxt%u: max Eager buffer RcvArray entries: %u\n", + rcd->ctxt, rcd->egrbufs.count); /* * Allocate array that will hold the eager buffer accounting @@ -308,8 +317,8 @@ struct hfi1_ctxtdata *hfi1_create_ctxtdata(struct hfi1_pportdata *ppd, u32 ctxt) */ if (rcd->egrbufs.size < hfi1_max_mtu) { rcd->egrbufs.size = __roundup_pow_of_two(hfi1_max_mtu); - dd_dev_info(dd, - "ctxt%u: eager bufs size too small. Adjusting to %zu\n", + hfi1_cdbg(PROC, + "ctxt%u: eager bufs size too small. Adjusting to %zu\n", rcd->ctxt, rcd->egrbufs.size); } rcd->egrbufs.rcvtid_size = HFI1_MAX_EAGER_BUFFER_SIZE; @@ -601,20 +610,19 @@ static int create_workqueues(struct hfi1_devdata *dd) for (pidx = 0; pidx < dd->num_pports; ++pidx) { ppd = dd->pport + pidx; if (!ppd->hfi1_wq) { - char wq_name[8]; /* 3 + 2 + 1 + 1 + 1 */ - - snprintf(wq_name, sizeof(wq_name), "hfi%d_%d", - dd->unit, pidx); ppd->hfi1_wq = - create_singlethread_workqueue(wq_name); + alloc_workqueue( + "hfi%d_%d", + WQ_SYSFS | WQ_HIGHPRI | WQ_CPU_INTENSIVE, + dd->num_sdma, + dd->unit, pidx); if (!ppd->hfi1_wq) goto wq_error; } } return 0; wq_error: - pr_err("create_singlethread_workqueue failed for port %d\n", - pidx + 1); + pr_err("alloc_workqueue failed for port %d\n", pidx + 1); for (pidx = 0; pidx < dd->num_pports; ++pidx) { ppd = dd->pport + pidx; if (ppd->hfi1_wq) { @@ -670,7 +678,7 @@ int hfi1_init(struct hfi1_devdata *dd, int reinit) dd->process_dma_send = hfi1_verbs_send_dma; dd->pio_inline_send = pio_copy; - if (is_a0(dd)) { + if (is_ax(dd)) { atomic_set(&dd->drop_packet, DROP_PACKET_ON); dd->do_drop = 1; } else { @@ -691,6 +699,18 @@ int hfi1_init(struct hfi1_devdata *dd, int reinit) if (ret) goto done; + /* allocate dummy tail memory for all receive contexts */ + dd->rcvhdrtail_dummy_kvaddr = dma_zalloc_coherent( + &dd->pcidev->dev, sizeof(u64), + &dd->rcvhdrtail_dummy_physaddr, + GFP_KERNEL); + + if (!dd->rcvhdrtail_dummy_kvaddr) { + dd_dev_err(dd, "cannot allocate dummy tail memory\n"); + ret = -ENOMEM; + goto done; + } + /* dd->rcd can be NULL if early initialization failed */ for (i = 0; dd->rcd && i < dd->first_user_ctxt; ++i) { /* @@ -1266,6 +1286,14 @@ static void cleanup_device_data(struct hfi1_devdata *dd) tmp = dd->rcd; dd->rcd = NULL; spin_unlock_irqrestore(&dd->uctxt_lock, flags); + + if (dd->rcvhdrtail_dummy_kvaddr) { + dma_free_coherent(&dd->pcidev->dev, sizeof(u64), + (void *)dd->rcvhdrtail_dummy_kvaddr, + dd->rcvhdrtail_dummy_physaddr); + dd->rcvhdrtail_dummy_kvaddr = NULL; + } + for (ctxt = 0; tmp && ctxt < dd->num_rcv_contexts; ctxt++) { struct hfi1_ctxtdata *rcd = tmp[ctxt]; @@ -1308,6 +1336,7 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { int ret = 0, j, pidx, initfail; struct hfi1_devdata *dd = NULL; + struct hfi1_pportdata *ppd; /* First, lock the non-writable module parameters */ HFI1_CAP_LOCK(); @@ -1322,6 +1351,7 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent) if (!encode_rcv_header_entry_size(hfi1_hdrq_entsize)) { hfi1_early_err(&pdev->dev, "Invalid HdrQ Entry size %u\n", hfi1_hdrq_entsize); + ret = -EINVAL; goto bail; } @@ -1403,8 +1433,14 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent) if (initfail || ret) { stop_timers(dd); flush_workqueue(ib_wq); - for (pidx = 0; pidx < dd->num_pports; ++pidx) + for (pidx = 0; pidx < dd->num_pports; ++pidx) { hfi1_quiet_serdes(dd->pport + pidx); + ppd = dd->pport + pidx; + if (ppd->hfi1_wq) { + destroy_workqueue(ppd->hfi1_wq); + ppd->hfi1_wq = NULL; + } + } if (!j) hfi1_device_remove(dd); if (!ret) @@ -1521,6 +1557,14 @@ int hfi1_create_rcvhdrq(struct hfi1_devdata *dd, struct hfi1_ctxtdata *rcd) reg = (dd->rcvhdrsize & RCV_HDR_SIZE_HDR_SIZE_MASK) << RCV_HDR_SIZE_HDR_SIZE_SHIFT; write_kctxt_csr(dd, rcd->ctxt, RCV_HDR_SIZE, reg); + + /* + * Program dummy tail address for every receive context + * before enabling any receive context + */ + write_kctxt_csr(dd, rcd->ctxt, RCV_HDR_TAIL_ADDR, + dd->rcvhdrtail_dummy_physaddr); + return 0; bail_free: @@ -1660,9 +1704,11 @@ int hfi1_setup_eagerbufs(struct hfi1_ctxtdata *rcd) rcd->egrbufs.numbufs = idx; rcd->egrbufs.size = alloced_bytes; - dd_dev_info(dd, "ctxt%u: Alloced %u rcv tid entries @ %uKB, total %zuKB\n", - rcd->ctxt, rcd->egrbufs.alloced, rcd->egrbufs.rcvtid_size, - rcd->egrbufs.size); + hfi1_cdbg(PROC, + "ctxt%u: Alloced %u rcv tid entries @ %uKB, total %zuKB\n", + rcd->ctxt, rcd->egrbufs.alloced, rcd->egrbufs.rcvtid_size, + rcd->egrbufs.size); + /* * Set the contexts rcv array head update threshold to the closest @@ -1683,13 +1729,14 @@ int hfi1_setup_eagerbufs(struct hfi1_ctxtdata *rcd) rcd->expected_count = MAX_TID_PAIR_ENTRIES * 2; rcd->expected_base = rcd->eager_base + egrtop; - dd_dev_info(dd, "ctxt%u: eager:%u, exp:%u, egrbase:%u, expbase:%u\n", - rcd->ctxt, rcd->egrbufs.alloced, rcd->expected_count, - rcd->eager_base, rcd->expected_base); + hfi1_cdbg(PROC, "ctxt%u: eager:%u, exp:%u, egrbase:%u, expbase:%u\n", + rcd->ctxt, rcd->egrbufs.alloced, rcd->expected_count, + rcd->eager_base, rcd->expected_base); if (!hfi1_rcvbuf_validate(rcd->egrbufs.rcvtid_size, PT_EAGER, &order)) { - dd_dev_err(dd, "ctxt%u: current Eager buffer size is invalid %u\n", - rcd->ctxt, rcd->egrbufs.rcvtid_size); + hfi1_cdbg(PROC, + "ctxt%u: current Eager buffer size is invalid %u\n", + rcd->ctxt, rcd->egrbufs.rcvtid_size); ret = -EINVAL; goto bail; } |