IB/hfi1,qib: Round 2 of hfi1/qib fixes for 4.9
Subsystems (3)
cover IB/hfi1,qib: Round 2 of hfi1/qib fixes for 4.9
Here is the next round of fixes and clean ups for hfi1/qib for 4.9. Mostly minor fixes but there is a fix for stable in here. It is marked to Cc the stable list in the commit message so no special handling should be needed on your part.
Patches should apply on your GitHub hfi1 branch and are availabe in my GitRepo as well:
https://github.com/ddalessa/kernel/tree/for-4.9
---
Dean Luick (2):
IB/hfi1: Extend i2c timeout
IB/hfi1: Act on external device timeout
Dennis Dalessandro (3):
IB/qib: Remove qpt_mask global IB/hfi1: Cleanup tasklet refs in comments IB/hfi1: Remove unused variable from devdata
Harish Chegondi (1):
IB/hfi1: Adjust hardware buffering parameter
Jakub Pawlak (1):
IB/hfi1: Fix resource release in context allocation
Jianxin Xiong (1):
IB/hfi1: Increase default settings of max_cqes and max_qps
Mike Marciniszyn (2):
IB/hfi1: Consolidate pio control masks into single definition IB/hfi1: Fix defered ack race with qp destroy
Sebastian Sanchez (3):
IB/hfi1: Remove filtering of Set(PkeyTable) in HFI SMA IB/hfi1: Do not read more than a SGE length IB/hfi1: Combine shift copy and byte copy for SGE reads
drivers/infiniband/hw/hfi1/chip.c | 8 + drivers/infiniband/hw/hfi1/chip.h | 6 + drivers/infiniband/hw/hfi1/file_ops.c | 17 ++ drivers/infiniband/hw/hfi1/hfi.h | 2 drivers/infiniband/hw/hfi1/init.c | 1 drivers/infiniband/hw/hfi1/mad.c | 6 - drivers/infiniband/hw/hfi1/pio_copy.c | 246 ++++++++------------------------- drivers/infiniband/hw/hfi1/qsfp.c | 2 drivers/infiniband/hw/hfi1/rc.c | 33 ++-- drivers/infiniband/hw/hfi1/ruc.c | 6 - drivers/infiniband/hw/hfi1/uc.c | 9 - drivers/infiniband/hw/hfi1/verbs.c | 40 ++++- drivers/infiniband/hw/hfi1/verbs.h | 3 drivers/infiniband/hw/qib/qib.h | 1 drivers/infiniband/hw/qib/qib_qp.c | 13 -- drivers/infiniband/hw/qib/qib_verbs.c | 2 16 files changed, 136 insertions(+), 259 deletions(-)
--
-Denny
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
A message that is not in the archive (sent off-list or not yet received): 20160925143656.10261.85231.stgit-9QXIwq+3FY+1XWohqUldA0EOCMrvLtNR@public.gmane.org
PATCH 1/13 IB/hfi1: Consolidate pio control masks into single definition
From: Mike Marciniszyn <[email protected]>
This allows for adding additional pages of adaptive pio opcode control including manufacturer specific ones.
--- drivers/infiniband/hw/hfi1/rc.c | 14 +------------- drivers/infiniband/hw/hfi1/uc.c | 9 +-------- drivers/infiniband/hw/hfi1/verbs.c | 36 +++++++++++++++++++++++++++--------- drivers/infiniband/hw/hfi1/verbs.h | 3 +++ 4 files changed, 32 insertions(+), 30 deletions(-)
drivers/infiniband/hw/hfi1/rc.c +1 -13
@@ -55,7 +55,7 @@#include "trace.h" /* cut down ridiculously long IB macro names */ -#define OP (x) IB_OPCODE_RC_##x +#define OP (x) RC_OP(x)/** * hfi1_add_retry_timer - add/start a retry timer
@@ -184,18 +184,6 @@ void hfi1_del_timers_sync(struct rvt_qp *qp)del_timer_sync (&priv->s_rnr_timer); } -/* only opcode mask for adaptive pio */ -const u32 rc_only_opcode = -BIT (OP (SEND_ONLY ) &0x1f ) | -BIT (OP (SEND_ONLY_WITH_IMMEDIATE &0x1f )) | -BIT (OP (RDMA_WRITE_ONLY &0x1f )) | -BIT (OP (RDMA_WRITE_ONLY_WITH_IMMEDIATE &0x1f )) | -BIT (OP (RDMA_READ_REQUEST &0x1f )) | -BIT (OP (ACKNOWLEDGE &0x1f )) | -BIT (OP (ATOMIC_ACKNOWLEDGE &0x1f )) | -BIT (OP (COMPARE_SWAP &0x1f )) | -BIT (OP (FETCH_ADD &0x1f )); -static u32 restart_sge (struct rvt_sge_state *ss,struct rvt_swqe *wqe,u32 psn,u32 pmtu) {
drivers/infiniband/hw/hfi1/uc.c +1 -8
@@ -50,14 +50,7 @@#include "qp.h" /* cut down ridiculously long IB macro names */ -#define OP (x) IB_OPCODE_UC_##x - -/* only opcode mask for adaptive pio */ -const u32 uc_only_opcode = -BIT (OP (SEND_ONLY ) &0x1f ) | -BIT (OP (SEND_ONLY_WITH_IMMEDIATE &0x1f )) | -BIT (OP (RDMA_WRITE_ONLY &0x1f )) | -BIT (OP (RDMA_WRITE_ONLY_WITH_IMMEDIATE &0x1f )); +#define OP (x) UC_OP(x)/** * hfi1_make_uc_req - construct a request packet (SEND, RDMA write)
drivers/infiniband/hw/hfi1/verbs.c +27 -9
@@ -403,6 +403,28 @@ static const opcode_handler opcode_handler_tbl[256] = { [IB_OPCODE_CNP ] = &hfi1_cnp_rcv }; +#define OPMASK 0x1f + +static const u32 pio_opmask[BIT (3 )] = { +/* RC */ + [IB_OPCODE_RC >>5 ] = +BIT (RC_OP (SEND_ONLY ) &OPMASK ) | +BIT (RC_OP (SEND_ONLY_WITH_IMMEDIATE ) &OPMASK ) | +BIT (RC_OP (RDMA_WRITE_ONLY ) &OPMASK ) | +BIT (RC_OP (RDMA_WRITE_ONLY_WITH_IMMEDIATE ) &OPMASK ) | +BIT (RC_OP (RDMA_READ_REQUEST ) &OPMASK ) | +BIT (RC_OP (ACKNOWLEDGE ) &OPMASK ) | +BIT (RC_OP (ATOMIC_ACKNOWLEDGE ) &OPMASK ) | +BIT (RC_OP (COMPARE_SWAP ) &OPMASK ) | +BIT (RC_OP (FETCH_ADD ) &OPMASK ), +/* UC */ + [IB_OPCODE_UC >>5 ] = +BIT (UC_OP (SEND_ONLY ) &OPMASK ) | +BIT (UC_OP (SEND_ONLY_WITH_IMMEDIATE ) &OPMASK ) | +BIT (UC_OP (RDMA_WRITE_ONLY ) &OPMASK ) | +BIT (UC_OP (RDMA_WRITE_ONLY_WITH_IMMEDIATE ) &OPMASK ), +}; +/* * System image GUID. */
@@ -1210,22 +1232,18 @@ static inline send_routine get_send_routine(struct rvt_qp *qp,case IB_QPT_GSI :case IB_QPT_UD :break ; -case IB_QPT_RC : -if (piothreshold && - qp->s_cur_size <=min (piothreshold, qp->pmtu) && - (BIT (get_opcode (h) &0x1f ) & rc_only_opcode) && -iowait_sdma_pending (&priv->s_iowait) ==0 && - !sdma_txreq_built (&tx->txreq)) -return dd->process_pio_send; -break ;case IB_QPT_UC : +case IB_QPT_RC : { +u8 op =get_opcode (h); +if (piothreshold && qp->s_cur_size <=min (piothreshold, qp->pmtu) && - (BIT (get_opcode (h) &0x1f ) & uc_only_opcode) && + (BIT (op &OPMASK ) & pio_opmask[op >>5 ]) &&iowait_sdma_pending (&priv->s_iowait) ==0 && !sdma_txreq_built (&tx->txreq))return dd->process_pio_send;break ; + }default :break ; }
drivers/infiniband/hw/hfi1/verbs.h +3 -0
@@ -97,6 +97,9 @@ struct hfi1_packet;#define IB_DEFAULT_GID_PREFIX cpu_to_be64(0xfe80000000000000ULL) +#define RC_OP (x) IB_OPCODE_RC_##x +#define UC_OP (x) IB_OPCODE_UC_##x +/* flags passed by hfi1_ib_rcv() */ enum {HFI1_HAS_GRH = (1 <<0 ),
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 2/13 IB/qib: Remove qpt_mask global
In reply to a message not in the archiveThere is no need to have a global qpt_mask as that does not support the multiple chip model which qib has. Instead rely on the value which exists already in the device data (dd).
--- drivers/infiniband/hw/qib/qib.h | 1 - drivers/infiniband/hw/qib/qib_qp.c | 13 +++---------- drivers/infiniband/hw/qib/qib_verbs.c | 2 -- 3 files changed, 3 insertions(+), 13 deletions(-)
drivers/infiniband/hw/qib/qib.h +0 -1
@@ -1132,7 +1132,6 @@ extern spinlock_t qib_devs_lock;extern struct qib_devdata *qib_lookup (int unit);extern u32 qib_cpulist_count;extern unsigned long *qib_cpulist; -extern u16 qpt_mask;extern unsigned qib_cc_table_size;int qib_init (struct qib_devdata *,int );
drivers/infiniband/hw/qib/qib_qp.c +3 -10
@@ -41,14 +41,6 @@#include "qib.h" -/* -* mask field which was present in now deleted qib_qpn_table -* is not present in rvt_qpn_table. Defining the same field -* as qpt_mask here instead of adding the mask field to -* rvt_qpn_table. -*/ -u16 qpt_mask; -static inline unsigned mk_qpn (struct rvt_qpn_table *qpt,struct rvt_qpn_map *map,unsigned off) {
@@ -57,7 +49,7 @@ static inline unsigned mk_qpn(struct rvt_qpn_table *qpt,static inline unsigned find_next_offset (struct rvt_qpn_table *qpt,struct rvt_qpn_map *map,unsigned off, -unsigned n) +unsigned n,u16 qpt_mask) {if (qpt_mask) { off++;
@@ -179,6 +171,7 @@ int qib_alloc_qpn(struct rvt_dev_info *rdi, struct rvt_qpn_table *qpt, struct qib_ibdev *verbs_dev = container_of(rdi, struct qib_ibdev, rdi); struct qib_devdata *dd = container_of(verbs_dev, struct qib_devdata, verbs_dev); +u16 qpt_mask = dd->qpn_mask;if (type ==IB_QPT_SMI || type ==IB_QPT_GSI ) {unsigned n;
@@ -215,7 +208,7 @@ int qib_alloc_qpn(struct rvt_dev_info *rdi, struct rvt_qpn_table *qpt, goto bail; } offset =find_next_offset (qpt, map, offset, - dd->n_krcv_queues); + dd->n_krcv_queues, qpt_mask); qpn =mk_qpn (qpt, map, offset);/* * This test differs from alloc_pidmap().
drivers/infiniband/hw/qib/qib_verbs.c +0 -2
@@ -1606,8 +1606,6 @@ int qib_register_ib_device(struct qib_devdata *dd)/* Only need to initialize non-zero fields. */ setup_timer (&dev->mem_timer, mem_timer, (unsigned long )dev); - qpt_mask = dd->qpn_mask; -INIT_LIST_HEAD (&dev->piowait);INIT_LIST_HEAD (&dev->dmawait);INIT_LIST_HEAD (&dev->txwait);
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 3/13 IB/hfi1: Remove filtering of Set(PkeyTable) in HFI SMA
In reply to a message not in the archiveFrom: Sebastian Sanchez <[email protected]>
The FM should have full control to set the pkeys in the driver pkey table. Remove filtering done by the driver.
--- drivers/infiniband/hw/hfi1/mad.c | 6 ------ 1 files changed, 0 insertions(+), 6 deletions(-)
drivers/infiniband/hw/hfi1/mad.c +0 -6
@@ -1406,12 +1406,6 @@ static int set_pkeys(struct hfi1_devdata *dd, u8 port, u16 *pkeys)if (key == okey)continue ;/* -* Don't update pkeys[2], if an HFI port without MgmtAllowed -* by neighbor is a switch. -*/ -if (i ==2 && !ppd->mgmt_allowed && ppd->neighbor_type ==1 ) -continue ; -/* * The SM gives us the complete PKey table. We have * to ensure that we put the PKeys in the matching * slots.
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 4/13 IB/hfi1: Increase default settings of max_cqes and max_qps
In reply to a message not in the archiveFrom: Jianxin Xiong <[email protected]>
The ib_write_bw test allows using up to 16384 QPs. When a relatively large number of QPs (within that range) is used, the test can fail because the number of CQ entries needed exceeds the limit set by the driver.
This patch increases the default setting of max_cqes from 0x2FFFF (196607) to 0x2FFFFF(3145727), which is sufficient to cover the maximum number needed by the ib_write_bw test (2097152). The default setting of max_qps is also increased from 16384 to 32768 to allow the test to run successfully with 16383 or 16384 QPs.
--- drivers/infiniband/hw/hfi1/verbs.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-)
drivers/infiniband/hw/hfi1/verbs.c +2 -2
@@ -76,7 +76,7 @@ static unsigned int hfi1_max_ahs = 0xFFFF;module_param_named (max_ahs, hfi1_max_ahs, uint,S_IRUGO );MODULE_PARM_DESC (max_ahs,"Maximum number of address handles to support" ); -unsigned int hfi1_max_cqes =0x2FFFF ; +unsigned int hfi1_max_cqes =0x2FFFFF ;module_param_named (max_cqes, hfi1_max_cqes, uint,S_IRUGO );MODULE_PARM_DESC (max_cqes,"Maximum number of completion queue entries to support" );
@@ -89,7 +89,7 @@ unsigned int hfi1_max_qp_wrs = 0x3FFF;module_param_named (max_qp_wrs, hfi1_max_qp_wrs, uint,S_IRUGO );MODULE_PARM_DESC (max_qp_wrs,"Maximum number of QP WRs to support" ); -unsigned int hfi1_max_qps =16384 ; +unsigned int hfi1_max_qps =32768 ;module_param_named (max_qps, hfi1_max_qps, uint,S_IRUGO );MODULE_PARM_DESC (max_qps,"Maximum number of QPs to support" );
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 5/13 IB/hfi1: Extend i2c timeout
In reply to a message not in the archiveFrom: Dean Luick <[email protected]>
Allow a longer timeout for i2c due to clock stretching and inaccurate jiffy timing when under a spin lock. This timeout is consistent with other i2c-algo-bit users.
--- drivers/infiniband/hw/hfi1/qsfp.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
drivers/infiniband/hw/hfi1/qsfp.c +1 -1
@@ -161,7 +161,7 @@ static struct hfi1_i2c_bus *init_i2c_bus(struct hfi1_devdata *dd, bus->algo.getsda = hfi1_getsda; bus->algo.getscl = hfi1_getscl; bus->algo.udelay =5 ; - bus->algo.timeout =usecs_to_jiffies (50 ); + bus->algo.timeout =usecs_to_jiffies (100000 ); bus->algo.data = bus; bus->adapter.owner =THIS_MODULE ;
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 6/13 IB/hfi1: Do not read more than a SGE length
In reply to a message not in the archiveFrom: Sebastian Sanchez <[email protected]>
In certain cases, if the tail of an SGE is not 8-byte aligned, bytes beyond the end to an 8-byte alignment can be read. Change the copy routine to avoid the over-read. Instead, stop on the final whole quad-word, then read the remaining bytes.
--- drivers/infiniband/hw/hfi1/pio_copy.c | 88 +++++++++++++++------------------ 1 files changed, 40 insertions(+), 48 deletions(-)
drivers/infiniband/hw/hfi1/pio_copy.c +40 -48
@@ -254,30 +254,6 @@ static inline void read_extra_bytes(struct pio_buf *pbuf, }/* -* Zero extra bytes from the end of pbuf->carry. -* -* NOTES: -* o zbytes <= old_bytes -*/ -static inline void zero_extra_bytes (struct pio_buf *pbuf,unsigned int zbytes) -{ -unsigned int remaining; - -if (zbytes ==0 )/* nothing to do */ -return ; - - remaining = pbuf->carry_bytes - zbytes;/* remaining bytes */ - -/* NOTE: zshift only guaranteed to work if remaining != 0 */ -if (remaining) - pbuf->carry.val64 = (pbuf->carry.val64 <<zshift (remaining)) - >>zshift (remaining); -else - pbuf->carry.val64 =0 ; - pbuf->carry_bytes = remaining; -} - -/* * Write a quad word using parts of pbuf->carry and the next 8 bytes of src. * Put the unused part of the next 8 bytes of src into the LSB bytes of * pbuf->carry with the upper bytes zeroed..
@@ -385,20 +361,6 @@ static inline void read_extra_bytes(struct pio_buf *pbuf, }/* -* Zero extra bytes from the end of pbuf->carry. -* -* We do not care about the value of unused bytes in carry, so just -* reduce the byte count. -* -* NOTES: -* o zbytes <= old_bytes -*/ -static inline void zero_extra_bytes (struct pio_buf *pbuf,unsigned int zbytes) -{ - pbuf->carry_bytes -= zbytes; -} - -/* * Write a quad word using parts of pbuf->carry and the next 8 bytes of src. * Put the unused part of the next 8 bytes of src into the low bytes of * pbuf->carry.
@@ -550,8 +512,8 @@ static void mid_copy_mix(struct pio_buf *pbuf, const void *from, size_t nbytes) {void __iomem *dest = pbuf->start + (pbuf->qw_written *sizeof (u64));void __iomem *dend;/* 8-byte data end */ -unsigned long qw_to_write = (pbuf->carry_bytes + nbytes) >>3 ; -unsigned long bytes_left = (pbuf->carry_bytes + nbytes) &0x7 ; +unsigned long qw_to_write = nbytes >>3 ; +unsigned long bytes_left = nbytes &0x7 ;/* calculate 8-byte data end */ dend = dest + (qw_to_write *sizeof (u64));
@@ -621,16 +583,46 @@ static void mid_copy_mix(struct pio_buf *pbuf, const void *from, size_t nbytes) dest +=sizeof (u64); } -/* adjust carry */ -if (pbuf->carry_bytes < bytes_left) { -/* need to read more */ -read_extra_bytes (pbuf, from, bytes_left - pbuf->carry_bytes); + pbuf->qw_written += qw_to_write; + +/* handle carry and left-over bytes */ +if (pbuf->carry_bytes + bytes_left >=8 ) { +unsigned long nread; + +/* there is enough to fill another qw - fill carry */ + nread =8 - pbuf->carry_bytes; +read_extra_bytes (pbuf, from, nread); + +/* +* One more write - but need to make sure dest is correct. +* Check for wrap and the possibility the write +* should be in SOP space. +* +* The two checks immediately below cannot both be true, hence +* the else. If we have wrapped, we cannot still be within the +* first block. Conversely, if we are still in the first block, +* we cannot have wrapped. We do the wrap check first as that +* is more likely. +*/ +/* adjust if we have wrapped */ +if (dest >= pbuf->end) + dest -= pbuf->size; +/* jump to the SOP range if within the first block */ +else if (pbuf->qw_written <PIO_BLOCK_QWS ) + dest +=SOP_DISTANCE ; + +/* flush out full carry */ +carry8_write8 (pbuf->carry, dest); + pbuf->qw_written++; + +/* now adjust and read the rest of the bytes into carry */ + bytes_left -= nread; + from += nread;/* from is now not aligned */ +read_low_bytes (pbuf, from, bytes_left); }else { -/* remove invalid bytes */ -zero_extra_bytes (pbuf, pbuf->carry_bytes - bytes_left); +/* not enough to fill another qw, append the rest to carry */ +read_extra_bytes (pbuf, from, bytes_left); } - - pbuf->qw_written += qw_to_write; }/*
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 7/13 IB/hfi1: Combine shift copy and byte copy for SGE reads
In reply to a message not in the archiveFrom: Sebastian Sanchez <[email protected]>
Prevent over-reading the SGE length by using byte
reads for non quad-word reads.
--- drivers/infiniband/hw/hfi1/pio_copy.c | 160 +++++---------------------------- 1 files changed, 23 insertions(+), 137 deletions(-)
drivers/infiniband/hw/hfi1/pio_copy.c +23 -137
@@ -165,9 +165,6 @@ void pio_copy(struct hfi1_devdata *dd, struct pio_buf *pbuf, u64 pbc,preempt_enable (); } -/* USE_SHIFTS is faster in user-space tests on a Xeon X5570 @ 2.93GHz */ -#define USE_SHIFTS 1 -#ifdef USE_SHIFTS /* * Handle carry bytes using shifts and masks. *
@@ -187,126 +184,6 @@ void pio_copy(struct hfi1_devdata *dd, struct pio_buf *pbuf, u64 pbc,#define mshift (x) (8 * (x))/* -* Read nbytes bytes from "from" and return them in the LSB bytes -* of pbuf->carry. Other bytes are zeroed. Any previous value -* pbuf->carry is lost. -* -* NOTES: -* o do not read from from if nbytes is zero -* o from may _not_ be u64 aligned -* o nbytes must not span a QW boundary -*/ -static inline void read_low_bytes (struct pio_buf *pbuf,const void *from, -unsigned int nbytes) -{ -unsigned long off; - -if (nbytes ==0 ) { - pbuf->carry.val64 =0 ; - }else { -/* align our pointer */ - off = (unsigned long )from &0x7 ; - from = (void *)((unsigned long )from & ~0x7l ); - pbuf->carry.val64 = ((*(u64 *)from) - <<zshift (nbytes + off))/* zero upper bytes */ - >>zshift (nbytes);/* place at bottom */ - } - pbuf->carry_bytes = nbytes; -} - -/* -* Read nbytes bytes from "from" and put them at the next significant bytes -* of pbuf->carry. Unused bytes are zeroed. It is expected that the extra -* read does not overfill carry. -* -* NOTES: -* o from may _not_ be u64 aligned -* o nbytes may span a QW boundary -*/ -static inline void read_extra_bytes (struct pio_buf *pbuf, -const void *from,unsigned int nbytes) -{ -unsigned long off = (unsigned long )from &0x7 ; -unsigned int room, xbytes; - -/* align our pointer */ - from = (void *)((unsigned long )from & ~0x7l ); - -/* check count first - don't read anything if count is zero */ -while (nbytes) { -/* find the number of bytes in this u64 */ - room =8 - off;/* this u64 has room for this many bytes */ - xbytes =min (room, nbytes); - -/* -* shift down to zero lower bytes, shift up to zero upper -* bytes, shift back down to move into place -*/ - pbuf->carry.val64 |= (((*(u64 *)from) - >>mshift (off)) - <<zshift (xbytes)) - >>zshift (xbytes + pbuf->carry_bytes); - off =0 ; - pbuf->carry_bytes += xbytes; - nbytes -= xbytes; - from +=sizeof (u64); - } -} - -/* -* Write a quad word using parts of pbuf->carry and the next 8 bytes of src. -* Put the unused part of the next 8 bytes of src into the LSB bytes of -* pbuf->carry with the upper bytes zeroed.. -* -* NOTES: -* o result must keep unused bytes zeroed -* o src must be u64 aligned -*/ -static inline void merge_write8 ( -struct pio_buf *pbuf, -void __iomem *dest, -const void *src) -{ -u64 new, temp; - - new = *(u64 *)src; - temp = pbuf->carry.val64 | (new <<mshift (pbuf->carry_bytes)); -writeq (temp, dest); - pbuf->carry.val64 = new >>zshift (pbuf->carry_bytes); -} - -/* -* Write a quad word using all bytes of carry. -*/ -static inline void carry8_write8 (union mix carry,void __iomem *dest) -{ -writeq (carry.val64, dest); -} - -/* -* Write a quad word using all the valid bytes of carry. If carry -* has zero valid bytes, nothing is written. -* Returns 0 on nothing written, non-zero on quad word written. -*/ -static inline int carry_write8 (struct pio_buf *pbuf,void __iomem *dest) -{ -if (pbuf->carry_bytes) { -/* unused bytes are always kept zeroed, so just write */ -writeq (pbuf->carry.val64, dest); -return 1 ; - } - -return 0 ; -} - -#else /* USE_SHIFTS */ -/* -* Handle carry bytes using byte copies. -* -* NOTE: the value the unused portion of carry is left uninitialized. -*/ - -/* * Jump copy - no-loop copy for < 8 bytes. */ static inline void jcopy (u8 *dest,const u8 *src,u32 n)
@@ -314,18 +191,25 @@ static inline void jcopy(u8 *dest, const u8 *src, u32 n)switch (n) {case 7 : *dest++ = *src++; +/* fall through */ case 6 : *dest++ = *src++; +/* fall through */ case 5 : *dest++ = *src++; +/* fall through */ case 4 : *dest++ = *src++; +/* fall through */ case 3 : *dest++ = *src++; +/* fall through */ case 2 : *dest++ = *src++; +/* fall through */ case 1 : *dest++ = *src++; +/* fall through */ } }
@@ -341,6 +225,7 @@ static inline void jcopy(u8 *dest, const u8 *src, u32 n)static inline void read_low_bytes (struct pio_buf *pbuf,const void *from,unsigned int nbytes) { + pbuf->carry.val64 =0 ;jcopy (&pbuf->carry.val8[0 ], from, nbytes); pbuf->carry_bytes = nbytes; }
@@ -362,25 +247,30 @@ static inline void read_extra_bytes(struct pio_buf *pbuf,/* * Write a quad word using parts of pbuf->carry and the next 8 bytes of src. -* Put the unused part of the next 8 bytes of src into the low bytes of -* pbuf->carry. +* Put the unused part of the next 8 bytes of src into the LSB bytes of +* pbuf->carry with the upper bytes zeroed.. +* +* NOTES: +* o result must keep unused bytes zeroed +* o src must be u64 aligned */ static inline void merge_write8 (struct pio_buf *pbuf, -void *dest, +void __iomem *dest,const void *src) { -u32 remainder =8 - pbuf->carry_bytes; +u64 new, temp; -jcopy (&pbuf->carry.val8[pbuf->carry_bytes], src, remainder); -writeq (pbuf->carry.val64, dest); -jcopy (&pbuf->carry.val8[0 ], src + remainder, pbuf->carry_bytes); + new = *(u64 *)src; + temp = pbuf->carry.val64 | (new <<mshift (pbuf->carry_bytes)); +writeq (temp, dest); + pbuf->carry.val64 = new >>zshift (pbuf->carry_bytes); }/* * Write a quad word using all bytes of carry. */ -static inline void carry8_write8 (union mix carry,void *dest) +static inline void carry8_write8 (union mix carry,void __iomem *dest) {writeq (carry.val64, dest); }
@@ -390,20 +280,16 @@ static inline void carry8_write8(union mix carry, void *dest)* has zero valid bytes, nothing is written. * Returns 0 on nothing written, non-zero on quad word written. */ -static inline int carry_write8 (struct pio_buf *pbuf,void *dest) +static inline int carry_write8 (struct pio_buf *pbuf,void __iomem *dest) {if (pbuf->carry_bytes) { -u64 zero =0 ; - -jcopy (&pbuf->carry.val8[pbuf->carry_bytes], (u8 *)&zero, -8 - pbuf->carry_bytes); +/* unused bytes are always kept zeroed, so just write */ writeq (pbuf->carry.val64, dest);return 1 ; }return 0 ; } -#endif /* USE_SHIFTS */ /* * Segmented PIO Copy - start
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 8/13 IB/hfi1: Fix defered ack race with qp destroy
In reply to a message not in the archiveFrom: Mike Marciniszyn <[email protected]>
There is a a bug in defered ack stuff that causes a race with the destroy of a QP.
A packet causes a defered ack to be pended by putting the QP into an rcd queue.
A return from the driver interrupt processing will process that rcd
queue of QPs and attempt to do a direct send of the ack. At this
point no locks are held and the above QP could now be put in the reset
state in the qp destroy logic. A refcount protects the QP while it
is in the rcd queue so it isn't going anywhere yet.
If the direct send fails to allocate a pio buffer, hfi1_schedule_send() is called to trigger sending an ack from the send engine. There is no state test in that code path.
The refcount is then dropped from the driver.c caller potentially allowing the qp destroy to continue from its refcount wait in parallel with the workqueue scheduling of the qp.
--- drivers/infiniband/hw/hfi1/rc.c | 5 ++++- 1 files changed, 4 insertions(+), 1 deletions(-)
drivers/infiniband/hw/hfi1/rc.c +4 -1
@@ -926,8 +926,10 @@ void hfi1_send_rc_ack(struct hfi1_ctxtdata *rcd, struct rvt_qp *qp,return ; queue_ack: -this_cpu_inc (*ibp->rvp.rc_qacks);spin_lock_irqsave (&qp->s_lock, flags); +if (!(ib_rvt_state_ops[qp->state] &RVT_PROCESS_RECV_OK )) + goto unlock; +this_cpu_inc (*ibp->rvp.rc_qacks); qp->s_flags |=RVT_S_ACK_PENDING |RVT_S_RESP_PENDING ; qp->s_nak_state = qp->r_nak_state; qp->s_ack_psn = qp->r_ack_psn;
@@ -936,6 +938,7 @@ queue_ack:/* Schedule the send tasklet. */ hfi1_schedule_send (qp); +unlock:spin_unlock_irqrestore (&qp->s_lock, flags); }
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 9/13 IB/hfi1: Act on external device timeout
In reply to a message not in the archiveFrom: Dean Luick <[email protected]>
Add missing external device timeout notification. Recognize it as a failed LNI signal from the 8051 firmware.
--- drivers/infiniband/hw/hfi1/chip.c | 4 +++- drivers/infiniband/hw/hfi1/chip.h | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-)
drivers/infiniband/hw/hfi1/chip.c +3 -1
@@ -971,7 +971,9 @@ static struct flag_table dc8051_info_err_flags[] = {FLAG_ENTRY0 ("Failed LNI(VerifyCap_1)" ,FAILED_LNI_VERIFY_CAP1 ),FLAG_ENTRY0 ("Failed LNI(VerifyCap_2)" ,FAILED_LNI_VERIFY_CAP2 ),FLAG_ENTRY0 ("Failed LNI(ConfigLT)" ,FAILED_LNI_CONFIGLT ), - FLAG_ENTRY0("Host Handshake Timeout", HOST_HANDSHAKE_TIMEOUT) +FLAG_ENTRY0 ("Host Handshake Timeout" ,HOST_HANDSHAKE_TIMEOUT ), +FLAG_ENTRY0 ("External Device Request Timeout" , + EXTERNAL_DEVICE_REQ_TIMEOUT), };/*
drivers/infiniband/hw/hfi1/chip.h +3 -1
@@ -254,12 +254,14 @@#define FAILED_LNI_VERIFY_CAP2 BIT(10)#define FAILED_LNI_CONFIGLT BIT(11)#define HOST_HANDSHAKE_TIMEOUT BIT(12) +#define EXTERNAL_DEVICE_REQ_TIMEOUT BIT(13)#define FAILED_LNI (FAILED_LNI_POLLING | FAILED_LNI_DEBOUNCE \ | FAILED_LNI_ESTBCOMM | FAILED_LNI_OPTEQ \ | FAILED_LNI_VERIFY_CAP1 \ | FAILED_LNI_VERIFY_CAP2 \ - | FAILED_LNI_CONFIGLT | HOST_HANDSHAKE_TIMEOUT) + | FAILED_LNI_CONFIGLT | HOST_HANDSHAKE_TIMEOUT \ + | EXTERNAL_DEVICE_REQ_TIMEOUT)/* DC_DC8051_DBG_ERR_INFO_SET_BY_8051.HOST_MSG - host message flags */ #define HOST_REQ_DONE BIT(0)
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 10/13 IB/hfi1: Adjust hardware buffering parameter
In reply to a message not in the archiveFrom: Harish Chegondi <[email protected]>
It was determined that 0x880 is a better value for hardware buffering, use it.
--- drivers/infiniband/hw/hfi1/chip.c | 4 ++-- drivers/infiniband/hw/hfi1/chip.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-)
drivers/infiniband/hw/hfi1/chip.c +2 -2
@@ -13385,9 +13385,9 @@ static void init_rbufs(struct hfi1_devdata *dd)/* * Give up after 1ms - maximum wait time. * -* RBuf size is 148KiB. Slowest possible is PCIe Gen1 x1 at +* RBuf size is 136KiB. Slowest possible is PCIe Gen1 x1 at * 250MB/s bandwidth. Lower rate to 66% for overhead to get: -* 148 KB / (66% * 250MB/s) = 920us +* 136 KB / (66% * 250MB/s) = 844us */ if (count++ >500 ) { dd_dev_err(dd,
drivers/infiniband/hw/hfi1/chip.h +1 -1
@@ -82,7 +82,7 @@*/ #define CM_VAU 3/* HFI link credit count, AKA receive buffer depth (RBUF_DEPTH) */ -#define CM_GLOBAL_CREDITS 0x940 +#define CM_GLOBAL_CREDITS 0x880/* Number of PKey entries in the HW */ #define MAX_PKEY_VALUES 16
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 11/13 IB/hfi1: Cleanup tasklet refs in comments
In reply to a message not in the archiveThe code no longer uses tasklets for the send engine. However it does use a tasklet for sdma but the send routines use a workqueue now days. Update the comments to reflect that. Make things more generic with saying "send engine" because that is what is being referred to.
--- drivers/infiniband/hw/hfi1/rc.c | 14 +++++++------- drivers/infiniband/hw/hfi1/ruc.c | 6 +++--- 2 files changed, 10 insertions(+), 10 deletions(-)
drivers/infiniband/hw/hfi1/rc.c +7 -7
@@ -835,7 +835,7 @@ bail_no_tx:* * This is called from hfi1_rc_rcv() and handle_receive_interrupt(). * Note that RDMA reads and atomics are handled in the -* send side QP state and tasklet. +* send side QP state and send engine. */ void hfi1_send_rc_ack (struct hfi1_ctxtdata *rcd,struct rvt_qp *qp,int is_fecn)
@@ -911,7 +911,7 @@ void hfi1_send_rc_ack(struct hfi1_ctxtdata *rcd, struct rvt_qp *qp,if (!pbuf) {/* * We have no room to send at the moment. Pass -* responsibility for sending the ACK to the send tasklet +* responsibility for sending the ACK to the send engine * so that when enough buffer space becomes available, * the ACK is sent ahead of other outgoing packets. */
@@ -936,7 +936,7 @@ queue_ack:if (is_fecn) qp->s_flags |=RVT_S_ECN ; -/* Schedule the send tasklet. */ +/* Schedule the send engine. */ hfi1_schedule_send (qp); unlock:spin_unlock_irqrestore (&qp->s_lock, flags);
@@ -1025,7 +1025,7 @@ done: qp->s_psn = psn;/* * Set RVT_S_WAIT_PSN as rc_complete() may start the timer -* asynchronously before the send tasklet can get scheduled. +* asynchronously before the send engine can get scheduled. * Doing it in hfi1_make_rc_req() is too late. */ if ((cmp_psn(qp->s_psn, qp->s_sending_hpsn) <= 0) &&
@@ -1946,7 +1946,7 @@ static noinline int rc_rcv_error(struct ib_other_headers *ohdr, void *data,case OP (FETCH_ADD ): {/* * If we didn't find the atomic request in the ack queue -* or the send tasklet is already backed up to send an +* or the send engine is already backed up to send an * earlier entry, we can ignore this request. */ if (!e || e->opcode != (u8 )opcode || old_req)
@@ -2433,7 +2433,7 @@ send_last: qp->r_nak_state =0 ; qp->r_head_ack_queue = next; -/* Schedule the send tasklet. */ +/* Schedule the send engine. */ qp->s_flags |=RVT_S_RESP_PENDING ;hfi1_schedule_send (qp);
@@ -2499,7 +2499,7 @@ send_last: qp->r_nak_state =0 ; qp->r_head_ack_queue = next; -/* Schedule the send tasklet. */ +/* Schedule the send engine. */ qp->s_flags |=RVT_S_RESP_PENDING ;hfi1_schedule_send (qp);
drivers/infiniband/hw/hfi1/ruc.c +3 -3
@@ -352,7 +352,7 @@ err:* * This is called from hfi1_do_send() to * forward a WQE addressed to the same HFI. -* Note that although we are single threaded due to the tasklet, we still +* Note that although we are single threaded due to the send engine, we still * have to protect against post_send(). We don't have to worry about * receive interrupts since this is a connected protocol and all packets * will pass through here.
@@ -846,7 +846,7 @@ void _hfi1_do_send(struct work_struct *work)* @work: contains a pointer to the QP * * Process entries in the send work queue until credit or queue is -* exhausted. Only allow one CPU to send a packet per QP (tasklet). +* exhausted. Only allow one CPU to send a packet per QP. * Otherwise, two threads could send packets out of order. */ void hfi1_do_send (struct rvt_qp *qp)
@@ -909,7 +909,7 @@ void hfi1_do_send(struct rvt_qp *qp)spin_unlock_irqrestore (&qp->s_lock, ps.flags);/* * If the packet cannot be sent now, return and -* the send tasklet will be woken up later. +* the send engine will be woken up later. */ if (hfi1_verbs_send (qp, &ps))return ;
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 12/13 IB/hfi1: Remove unused variable from devdata
In reply to a message not in the archiveWe no longer use an error tasklet. Remove it from the hfi1_devdata structure.
--- drivers/infiniband/hw/hfi1/hfi.h | 2 -- 1 files changed, 0 insertions(+), 2 deletions(-)
drivers/infiniband/hw/hfi1/hfi.h +0 -2
@@ -1061,8 +1061,6 @@ struct hfi1_devdata {u8 psxmitwait_supported;/* cycle length of PS* counters in HW (in picoseconds) */ u16 psxmitwait_check_rate; -/* high volume overflow errors deferred to tasklet */ -struct tasklet_struct error_tasklet;/* MSI-X information */ struct hfi1_msix_entry *msix_entries;
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 13/13 IB/hfi1: Fix resource release in context allocation
In reply to a message not in the archiveFrom: Jakub Pawlak <[email protected]>
Correct resource free in allocate_ctxt() function. When context creation fails allocated resources are properly released and pointer in receive context data table is set back to NULL.
--- drivers/infiniband/hw/hfi1/file_ops.c | 17 ++++++++++++----- drivers/infiniband/hw/hfi1/init.c | 1 + 2 files changed, 13 insertions(+), 5 deletions(-)
drivers/infiniband/hw/hfi1/file_ops.c +12 -5
@@ -978,14 +978,16 @@ static int allocate_ctxt(struct file *fp, struct hfi1_devdata *dd,*/ uctxt->sc =sc_alloc (dd,SC_USER , uctxt->rcvhdrqentsize, uctxt->dd->node); -if (!uctxt->sc) -return -ENOMEM ; - +if (!uctxt->sc) { + ret = -ENOMEM ; + goto ctxdata_free; + }hfi1_cdbg (PROC ,"allocated send context %u(%u)\n" , uctxt->sc->sw_index, uctxt->sc->hw_context); ret =sc_enable (uctxt->sc);if (ret) -return ret; + goto ctxdata_free; +/* * Setup shared context resources if the user-level has requested * shared contexts and this is the 'master' process.
@@ -999,7 +1001,7 @@ static int allocate_ctxt(struct file *fp, struct hfi1_devdata *dd,* send context because it will be done during file close */ if (ret) -return ret; + goto ctxdata_free; } uctxt->userversion = uinfo->userversion; uctxt->flags = hfi1_cap_mask;/* save current flag state */
@@ -1019,6 +1021,11 @@ static int allocate_ctxt(struct file *fp, struct hfi1_devdata *dd, fd->uctxt = uctxt;return 0 ; + +ctxdata_free: + dd->rcd[ctxt] =NULL ; +hfi1_free_ctxtdata (dd, uctxt); +return ret; } static int init_subctxts(struct hfi1_ctxtdata *uctxt,
drivers/infiniband/hw/hfi1/init.c +1 -0
@@ -336,6 +336,7 @@ struct hfi1_ctxtdata *hfi1_create_ctxtdata(struct hfi1_pportdata *ppd, u32 ctxt, }return rcd; bail: + dd->rcd[ctxt] =NULL ;kfree (rcd->egrbufs.rcvtids);kfree (rcd->egrbufs.buffers);kfree (rcd);
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Quoted 28 lines · Dennis Dalessandro
Here is the next round of fixes and clean ups for hfi1/qib for 4.9. Mostly minor fixes but there is a fix for stable in here. It is marked to Cc the stable list in the commit message so no special handling should be needed on your part.
Patches should apply on your GitHub hfi1 branch and are availabe in my GitRepo as well:
https://github.com/ddalessa/kernel/tree/for-4.9---
Dean Luick (2):
IB/hfi1: Extend i2c timeout
IB/hfi1: Act on external device timeoutDennis Dalessandro (3):
IB/qib: Removeqpt_maskglobal IB/hfi1: Cleanup tasklet refs in comments IB/hfi1: Remove unused variable from devdataHarish Chegondi (1):
IB/hfi1: Adjust hardware buffering parameterJakub Pawlak (1):
IB/hfi1: Fix resource release in context allocationJianxin Xiong (1):
IB/hfi1: Increase default settings ofmax_cqesandmax_qps
Quoted 8 lines
Mike Marciniszyn (2):
IB/hfi1: Consolidate pio control masks into single definition IB/hfi1: Fix defered ack race with qp destroySebastian Sanchez (3):
IB/hfi1: Remove filtering of Set(PkeyTable) in HFI SMA IB/hfi1: Do not read more than a SGE length IB/hfi1: Combine shift copy and byte copy for SGE reads
Thanks, series applied.
Signature · 2 lines
Doug Ledford <[email protected]> GPG Key ID: 0E572FDD