staging/rdma/hfi1: Fix bugs and performance issues
Subsystems (2)
v3 cover staging/rdma/hfi1: Fix bugs and performance issues
From: Ira Weiny <[email protected]>
The following are fixes to the hfi1 driver for stability, security, and performance.
Changes from v2:
Rebased to latest staging-next
Update commit messages
Squashed these patches together:
0006-staging-rdma-hfi1-Add-coalescing-support-for-SDMA-TX.patch 0007-staging-rdma-hfi1-Fix-sparse-error-in-sdma.h-file.patch
Split some patches for clarity (new patches):
0013-staging-rdma-hfi1-Wrong-cast-breaks-desired-pointer-.patch 0016-staging-rdma-hfi1-Increase-SDMA-descriptor-queue-siz.patch
[PATCH v3 14/23] staging/rdma/hfi1: Implement Expected Receive TID caching
Fix random Kconfig 0-day build error
Fix leak of random memory to user space caught by Dan Carpenter Separate out pointer bug fix into a previous patch Change error checks in case statement per Dan's comments
[PATCH v3 15/23] staging/rdma/hfi1: Allow tuning of SDMA interrupt rate
Squash in a patch with a recommended default value of 64.
Changes from v1:
Reviewed each patch for new features. Found 2 which fixed congestion notification in some corner cases but they could be considered additional features, so they were dropped.
Split code clean up from patch 14 "Implement Expected Receive TID caching" into a separate patch.
Updated some commit messages to be clear how those patches fixed the driver.
Caz Yokoyama (1):
staging/rdma/hfi1: Reset firmware instead of reloading Sbus
Dean Luick (4):
staging/rdma/hfi1: Extend the offline timeout staging/rdma/hfi1: Add a schedule in send thread staging/rdma/hfi1: Add irqsaves in the packet processing path staging/rdma/hfi1: Thread the receive interrupt.
Easwar Hariharan (4):
staging/rdma/hfi1: Fix code to reset ASIC CSRs on FLR staging/rdma/hfi1: Remove QSFP_ENABLED from HFI capability mask staging/rdma/hfi1: Fix port bounce issues with 0.22 DC firmware staging/rdma/hfi1: Load SBus firmware once per ASIC
Ignacio Hernandez (1):
staging/rdma/hfi1: Increase SDMA descriptor queue size
Jareer Abdel-Qader (1):
staging/rdma/hfi1: close shared context security hole
Jubin John (2):
staging/rdma/hfi1: Add unit # to verbs txreq cache name staging/rdma/hfi1: Update driver version string to 0.9-294
Mike Marciniszyn (3):
staging/rdma/hfi1: Fix regression in send performance staging/rdma/hfi: modify workqueue for parallelism staging/rdma/hfi1: add additional rc traces
Mitko Haralanov (5):
staging/rdma/hfi1: Prevent silent data corruption with user SDMA staging/rdma/hfi1: Macro code clean up staging/rdma/hfi1: Wrong cast breaks desired pointer arithmetic staging/rdma/hfi1: Implement Expected Receive TID caching staging/rdma/hfi1: Allow tuning of SDMA interrupt rate
Niranjana Vishwanathapura (1):
staging/rdma/hfi1: Add coalescing support for SDMA TX descriptors
Vennila Megavannan (1):
staging/rdma/hfi1: Prevent host software lock up
drivers/staging/rdma/hfi1/Kconfig | 1 + drivers/staging/rdma/hfi1/Makefile | 2 +- drivers/staging/rdma/hfi1/chip.c | 157 +++- drivers/staging/rdma/hfi1/chip.h | 2 + drivers/staging/rdma/hfi1/common.h | 19 +- drivers/staging/rdma/hfi1/driver.c | 77 +- drivers/staging/rdma/hfi1/file_ops.c | 497 ++----------- drivers/staging/rdma/hfi1/firmware.c | 37 +- drivers/staging/rdma/hfi1/hfi.h | 85 ++- drivers/staging/rdma/hfi1/init.c | 23 +- drivers/staging/rdma/hfi1/iowait.h | 6 +- drivers/staging/rdma/hfi1/mad.c | 4 +- drivers/staging/rdma/hfi1/pcie.c | 15 +- drivers/staging/rdma/hfi1/pio.c | 14 +- drivers/staging/rdma/hfi1/qp.c | 47 +- drivers/staging/rdma/hfi1/qp.h | 51 ++ drivers/staging/rdma/hfi1/qsfp.c | 13 +- drivers/staging/rdma/hfi1/rc.c | 23 +- drivers/staging/rdma/hfi1/ruc.c | 55 +- drivers/staging/rdma/hfi1/sdma.c | 164 ++++- drivers/staging/rdma/hfi1/sdma.h | 82 ++- drivers/staging/rdma/hfi1/trace.c | 4 +- drivers/staging/rdma/hfi1/trace.h | 180 +++-- drivers/staging/rdma/hfi1/ud.c | 1 + drivers/staging/rdma/hfi1/user_exp_rcv.c | 1171 ++++++++++++++++++++++++++++++ drivers/staging/rdma/hfi1/user_exp_rcv.h | 82 +++ drivers/staging/rdma/hfi1/user_pages.c | 110 +-- drivers/staging/rdma/hfi1/user_sdma.c | 103 ++- drivers/staging/rdma/hfi1/user_sdma.h | 10 +- drivers/staging/rdma/hfi1/verbs.c | 50 +- drivers/staging/rdma/hfi1/verbs.h | 9 +- include/uapi/rdma/hfi/hfi1_user.h | 46 +- 32 files changed, 2177 insertions(+), 963 deletions(-) create mode 100644 drivers/staging/rdma/hfi1/user_exp_rcv.c create mode 100644 drivers/staging/rdma/hfi1/user_exp_rcv.h
Signature · 6 lines
1.8.2 -- 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): 1445869729-7507-1-git-send-email-ira.weiny-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org
PATCH v3 1/23 staging/rdma/hfi1: Fix regression in send performance
From: Mike Marciniszyn <[email protected]>
The clear_ahg call is new in hfi1 vs qib. For small messages the progress routine always builds one and clears out the ahg state when the queue has gone to empty which is the predominant case for small messages.
Inline the routine and avoid the call to sdma_ahg_free to mitigate the performance impact. Finally, move the routine to qp.h for scope reasons.
--- drivers/staging/rdma/hfi1/qp.h | 15 +++++++++++++++ drivers/staging/rdma/hfi1/ruc.c | 13 ------------- drivers/staging/rdma/hfi1/verbs.h | 2 -- 3 files changed, 15 insertions(+), 15 deletions(-)
drivers/staging/rdma/hfi1/qp.h +15 -0
@@ -52,6 +52,7 @@#include <linux/hash.h> #include "verbs.h" +#include "sdma.h" #define QPN_MAX (1 << 24)#define QPNMAP_ENTRIES (QPN_MAX / PAGE_SIZE / BITS_PER_BYTE)
@@ -117,6 +118,20 @@ static inline struct hfi1_qp *hfi1_lookup_qpn(struct hfi1_ibport *ibp, }/** +* clear_ahg - reset ahg status in qp +* @qp - qp pointer +*/ +static inline void clear_ahg (struct hfi1_qp *qp) +{ + qp->s_hdr->ahgcount =0 ; + qp->s_flags &= ~(HFI1_S_AHG_VALID |HFI1_S_AHG_CLEAR ); +if (qp->s_sde && qp->s_ahgidx >=0 ) +sdma_ahg_free (qp->s_sde, qp->s_ahgidx); + qp->s_ahgidx =-1 ; + qp->s_sde =NULL ; +} + +/** * hfi1_error_qp - put a QP into the error state * @qp: the QP to put into the error state * @err: the receive completion error to signal if a RWQE is active
drivers/staging/rdma/hfi1/ruc.c +0 -13
@@ -695,19 +695,6 @@ u32 hfi1_make_grh(struct hfi1_ibport *ibp, struct ib_grh *hdr,return sizeof (struct ib_grh ) /sizeof (u32); } -/* -* free_ahg - clear ahg from QP -*/ -void clear_ahg (struct hfi1_qp *qp) -{ - qp->s_hdr->ahgcount =0 ; - qp->s_flags &= ~(HFI1_S_AHG_VALID |HFI1_S_AHG_CLEAR ); -if (qp->s_sde) -sdma_ahg_free (qp->s_sde, qp->s_ahgidx); - qp->s_ahgidx =-1 ; - qp->s_sde =NULL ; -} -#define BTH2_OFFSET (offsetof(struct hfi1_pio_header, hdr.u.oth.bth[2]) / 4)/**
drivers/staging/rdma/hfi1/verbs.h +0 -2
@@ -1078,8 +1078,6 @@ int hfi1_ruc_check_hdr(struct hfi1_ibport *ibp, struct hfi1_ib_header *hdr,u32 hfi1_make_grh (struct hfi1_ibport *ibp,struct ib_grh *hdr,struct ib_global_route *grh,u32 hwords,u32 nwords); -void clear_ahg (struct hfi1_qp *qp); -void hfi1_make_ruc_header (struct hfi1_qp *qp,struct hfi1_other_headers *ohdr,u32 bth0,u32 bth2,int middle);
Signature · 6 lines
1.8.2 -- 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 v3 3/23 staging/rdma/hfi1: Extend the offline timeout
In reply to a message not in the archiveFrom: Dean Luick <[email protected]>
The latest version of the 8051 firmware will wait longer when bringing the link down. Extend the driver's timeout to go with that.
--- drivers/staging/rdma/hfi1/chip.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/staging/rdma/hfi1/chip.c +1 -1
@@ -6205,7 +6205,7 @@ static int goto_offline(struct hfi1_pportdata *ppd, u8 rem_reason)if (do_wait) {/* it can take a while for the link to go down */ - ret =wait_phy_linkstate (dd,PLS_OFFLINE ,5000 ); + ret =wait_phy_linkstate (dd,PLS_OFFLINE ,10000 );if (ret <0 )return ret; }
Signature · 6 lines
1.8.2 -- 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 v3 7/23 staging/rdma/hfi1: close shared context security hole
In reply to a message not in the archiveFrom: Jareer Abdel-Qader <[email protected]>
Driver does not verify userid for shared context assignments, allowing malicious user access.
Reviewed by: Mike Marciniszyn <[email protected]>
--- drivers/staging/rdma/hfi1/file_ops.c | 1 + 1 file changed, 1 insertion(+)
drivers/staging/rdma/hfi1/file_ops.c +1 -0
@@ -948,6 +948,7 @@ static int find_shared_ctxt(struct file *fp,/* Skip ctxt if it doesn't match the requested one */ if (memcmp (uctxt->uuid, uinfo->uuid,sizeof (uctxt->uuid)) || + uctxt->jkey !=generate_jkey (current_uid ()) || uctxt->subctxt_id != uinfo->subctxt_id || uctxt->subctxt_cnt != uinfo->subctxt_cnt)continue ;
Signature · 6 lines
1.8.2 -- 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 v3 9/23 staging/rdma/hfi1: Add a schedule in send thread
In reply to a message not in the archiveFrom: Dean Luick <[email protected]>
When under heavy load, the send handler can run too long without allowing other tasks to run. Add a conditional resched to break this up.
--- drivers/staging/rdma/hfi1/chip.c | 10 ++++++++++ drivers/staging/rdma/hfi1/chip.h | 1 + drivers/staging/rdma/hfi1/ruc.c | 12 ++++++++++++ drivers/staging/rdma/hfi1/verbs.h | 1 + 4 files changed, 24 insertions(+)
drivers/staging/rdma/hfi1/chip.c +10 -0
@@ -1530,6 +1530,14 @@ static u64 access_sw_kmem_wait(const struct cntr_entry *entry,return dd->verbs_dev.n_kmem_wait; } +static u64 access_sw_send_schedule (const struct cntr_entry *entry, +void *context,int vl,int mode,u64 data) +{ +struct hfi1_devdata *dd = (struct hfi1_devdata *)context; + +return dd->verbs_dev.n_send_schedule; +} +#define def_access_sw_cpu (cntr) \ static u64 access_sw_cpu_##cntr(const struct cntr_entry *entry, \ void *context, int vl, int mode, u64 data) \
@@ -1720,6 +1728,8 @@ static struct cntr_entry dev_cntrs[DEV_CNTR_LAST] = { access_sw_pio_wait), [C_SW_KMEM_WAIT ] =CNTR_ELEM ("KmemWait" ,0 ,0 ,CNTR_NORMAL , access_sw_kmem_wait), +[C_SW_SEND_SCHED ] =CNTR_ELEM ("SendSched" ,0 ,0 ,CNTR_NORMAL , + access_sw_send_schedule), };static struct cntr_entry port_cntrs[PORT_CNTR_LAST ] = {
drivers/staging/rdma/hfi1/chip.h +1 -0
@@ -787,6 +787,7 @@ enum {C_SW_VTX_WAIT ,C_SW_PIO_WAIT ,C_SW_KMEM_WAIT , +C_SW_SEND_SCHED , DEV_CNTR_LAST /* Must be kept last */ };
drivers/staging/rdma/hfi1/ruc.c +12 -0
@@ -820,6 +820,9 @@ void hfi1_make_ruc_header(struct hfi1_qp *qp, struct hfi1_other_headers *ohdr, ohdr->bth[2 ] =cpu_to_be32 (bth2); } +/* when sending, force a reschedule every one of these periods */ +#define SEND_RESCHED_TIMEOUT (5 * HZ)/* 5s in jiffies */ +/** * hfi1_do_send - perform a send on a QP * @work: contains a pointer to the QP
@@ -836,6 +839,7 @@ void hfi1_do_send(struct work_struct *work)struct hfi1_pportdata *ppd =ppd_from_ibp (ibp);int (*make_req)(struct hfi1_qp *qp);unsigned long flags; +unsigned long timeout; if ((qp->ibqp.qp_type == IB_QPT_RC || qp->ibqp.qp_type == IB_QPT_UC) &&
@@ -864,6 +868,7 @@ void hfi1_do_send(struct work_struct *work)spin_unlock_irqrestore (&qp->s_lock, flags); + timeout = jiffies +SEND_RESCHED_TIMEOUT ; do { /* Check for a constructed packet to be sent. */ if (qp->s_hdrwords != 0) {
@@ -877,6 +882,13 @@ void hfi1_do_send(struct work_struct *work)/* Record that s_hdr is empty. */ qp->s_hdrwords =0 ; } + +/* allow other tasks to run */ +if (unlikely (time_after (jiffies, timeout))) { +cond_resched (); + ppd->dd->verbs_dev.n_send_schedule++; + timeout = jiffies +SEND_RESCHED_TIMEOUT ; + } }while (make_req (qp)); }
drivers/staging/rdma/hfi1/verbs.h +1 -0
@@ -754,6 +754,7 @@ struct hfi1_ibdev {u64 n_piowait;u64 n_txwait;u64 n_kmem_wait; +u64 n_send_schedule;u32 n_pds_allocated;/* number of PDs allocated for device */ spinlock_t n_pds_lock;
Signature · 6 lines
1.8.2 -- 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 v3 12/23 staging/rdma/hfi1: Macro code clean up
In reply to a message not in the archiveFrom: Mitko Haralanov <[email protected]>
Clean up the context and sdma macros and move them to a more logical place in hfi.h
--- drivers/staging/rdma/hfi1/hfi.h | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-)
drivers/staging/rdma/hfi1/hfi.h +10 -12
@@ -1104,6 +1104,16 @@ struct hfi1_filedata {int rec_cpu_num; }; +/* for use in system calls, where we want to know device type, etc. */ +#define fp_to_fd (fp) ((struct hfi1_filedata *)(fp)->private_data) +#define ctxt_fp (fp) (fp_to_fd((fp))->uctxt) +#define subctxt_fp (fp) (fp_to_fd((fp))->subctxt) +#define tidcursor_fp (fp) (fp_to_fd((fp))->tidcursor) +#define user_sdma_pkt_fp (fp) (fp_to_fd((fp))->pq) +#define user_sdma_comp_fp (fp) (fp_to_fd((fp))->cq) +#define notifier_fp (fp) (fp_to_fd((fp))->mn) +#define rb_fp (fp) (fp_to_fd((fp))->tid_rb_root) +extern struct list_head hfi1_dev_list;extern spinlock_t hfi1_devs_lock;struct hfi1_devdata *hfi1_lookup (int unit);
@@ -1411,18 +1421,6 @@ int snoop_send_pio_handler(struct hfi1_qp *qp, struct ahg_ib_header *ibhdr,void snoop_inline_pio_send (struct hfi1_devdata *dd,struct pio_buf *pbuf,u64 pbc,const void *from,size_t count); -/* for use in system calls, where we want to know device type, etc. */ -#define ctxt_fp (fp) \ - (((struct hfi1_filedata *)(fp)->private_data)->uctxt) -#define subctxt_fp (fp) \ - (((struct hfi1_filedata *)(fp)->private_data)->subctxt) -#define tidcursor_fp (fp) \ - (((struct hfi1_filedata *)(fp)->private_data)->tidcursor) -#define user_sdma_pkt_fp (fp) \ - (((struct hfi1_filedata *)(fp)->private_data)->pq) -#define user_sdma_comp_fp (fp) \ - (((struct hfi1_filedata *)(fp)->private_data)->cq) -static inline struct hfi1_devdata *dd_from_ppd (struct hfi1_pportdata *ppd) {return ppd->dd;
Signature · 6 lines
1.8.2 -- 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): 1445869729-7507-13-git-send-email-ira.weiny-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org
Re: [PATCH v3 12/23] staging/rdma/hfi1: Macro code clean up
Quoted 18 lines · On Mon, Oct 26, 2015 at 10:28:38AM -0400…
From: Mitko Haralanov <[email protected]>
Clean up the context and sdma macros and move them to a more logical place in
hfi.hSigned-off-by Mitko Haralanov <[email protected]>Signed-off-by Ira Weiny <[email protected]>--- drivers/staging/rdma/hfi1/hfi.h | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-)drivers/staging/rdma/hfi1/hfi.h +0
-0@@ -1104,6 +1104,16 @@ struct hfi1_filedata {int rec_cpu_num; };
drivers/staging/rdma/hfi1/hfi.h struct hfi1_filedata { · line 1115
Quoted 10 lines
drivers/staging/rdma/hfi1/hfi.h +9
-0+/* for use in system calls, where we want to know device type, etc. */ +#define fp_to_fd (fp) ((struct hfi1_filedata *)(fp)->private_data) +#define ctxt_fp (fp) (fp_to_fd((fp))->uctxt) +#define subctxt_fp (fp) (fp_to_fd((fp))->subctxt) +#define tidcursor_fp (fp) (fp_to_fd((fp))->tidcursor) +#define user_sdma_pkt_fp (fp) (fp_to_fd((fp))->pq) +#define user_sdma_comp_fp (fp) (fp_to_fd((fp))->cq) +#define notifier_fp (fp) (fp_to_fd((fp))->mn) +#define rb_fp (fp) (fp_to_fd((fp))->tid_rb_root)
Ick, no, don't do this, just spell it all out (odds are you will see tht you can make the code simpler...) If you don't know what "cq" or "pq" are, then name them properly.
These need to be all removed.
thanks,
greg k-h
--
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): [email protected]
Re: [PATCH v3 12/23] staging/rdma/hfi1: Macro code clean up
Quoted 34 lines · Greg KH
Quoted 18 lines · On Mon, Oct 26, 2015 at 10:28:38AM -0400…
From: Mitko Haralanov <[email protected]>
Clean up the context and sdma macros and move them to a more logical place in
hfi.hSigned-off-by Mitko Haralanov <[email protected]>Signed-off-by Ira Weiny <[email protected]>--- drivers/staging/rdma/hfi1/hfi.h | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-)drivers/staging/rdma/hfi1/hfi.h +0
-0@@ -1104,6 +1104,16 @@ struct hfi1_filedata {int rec_cpu_num; };drivers/staging/rdma/hfi1/hfi.h struct hfi1_filedata { · line 1115
Quoted 10 lines
drivers/staging/rdma/hfi1/hfi.h +9
-0+/* for use in system calls, where we want to know device type, etc. */ +#define fp_to_fd (fp) ((struct hfi1_filedata *)(fp)->private_data) +#define ctxt_fp (fp) (fp_to_fd((fp))->uctxt) +#define subctxt_fp (fp) (fp_to_fd((fp))->subctxt) +#define tidcursor_fp (fp) (fp_to_fd((fp))->tidcursor) +#define user_sdma_pkt_fp (fp) (fp_to_fd((fp))->pq) +#define user_sdma_comp_fp (fp) (fp_to_fd((fp))->cq) +#define notifier_fp (fp) (fp_to_fd((fp))->mn) +#define rb_fp (fp) (fp_to_fd((fp))->tid_rb_root)Ick, no, don't do this, just spell it all out (odds are you will see tht you can make the code simpler...) If you don't know what "cq" or "pq" are, then name them properly.
Quoted 1 line
These need to be all removed.
Ok.
Can I add the removal of these macros to the TODO list and get this patch accepted in the interm?
Many of the patches I am queueing up to submit as well as one in this series do not apply cleanly without this change. It will be much easier if I can get everything applied and then do a global clean up of these macros after the fact.
Thanks,
Ira
--
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): 20151027205115.GB32118-W4f6Xiosr+yv7QzWx2u06xL4W9x8LtSr@public.gmane.org
Re: [PATCH v3 12/23] staging/rdma/hfi1: Macro code clean up
Quoted 35 lines · ira.weiny
Quoted 34 lines · Greg KH
Quoted 18 lines · On Mon, Oct 26, 2015 at 10:28:38AM -0400…
From: Mitko Haralanov <[email protected]>
Clean up the context and sdma macros and move them to a more logical place in
hfi.hSigned-off-by Mitko Haralanov <[email protected]>Signed-off-by Ira Weiny <[email protected]>--- drivers/staging/rdma/hfi1/hfi.h | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-)drivers/staging/rdma/hfi1/hfi.h +0
-0@@ -1104,6 +1104,16 @@ struct hfi1_filedata {int rec_cpu_num; };drivers/staging/rdma/hfi1/hfi.h struct hfi1_filedata { · line 1115
Quoted 10 lines
drivers/staging/rdma/hfi1/hfi.h +9
-0+/* for use in system calls, where we want to know device type, etc. */ +#define fp_to_fd (fp) ((struct hfi1_filedata *)(fp)->private_data) +#define ctxt_fp (fp) (fp_to_fd((fp))->uctxt) +#define subctxt_fp (fp) (fp_to_fd((fp))->subctxt) +#define tidcursor_fp (fp) (fp_to_fd((fp))->tidcursor) +#define user_sdma_pkt_fp (fp) (fp_to_fd((fp))->pq) +#define user_sdma_comp_fp (fp) (fp_to_fd((fp))->cq) +#define notifier_fp (fp) (fp_to_fd((fp))->mn) +#define rb_fp (fp) (fp_to_fd((fp))->tid_rb_root)Ick, no, don't do this, just spell it all out (odds are you will see tht you can make the code simpler...) If you don't know what "cq" or "pq" are, then name them properly.
Quoted 6 lines
Quoted 1 line
These need to be all removed.
Ok.
Can I add the removal of these macros to the TODO list and get this patch accepted in the interm?
Nope, sorry, why would I accept a known-problem patch? Would you do such a thing?
Quoted 4 lines
Many of the patches I am queueing up to submit as well as one in this series do not apply cleanly without this change. It will be much easier if I can get everything applied and then do a global clean up of these macros after the fact.
But you would have no incentive to do that if I take this patch now :)
thanks,
greg k-h
--
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): [email protected]
Re: [PATCH v3 12/23] staging/rdma/hfi1: Macro code clean up
Quoted 6 lines
Quoted 2 lines
Can I add the removal of these macros to the TODO list and get this patch accepted in the interm?
Nope, sorry, why would I accept a known-problem patch? Would you do such a thing?
Quoted 7 lines
Quoted 4 lines
Many of the patches I am queueing up to submit as well as one in this series do not apply cleanly without this change. It will be much easier if I can get everything applied and then do a global clean up of these macros after the fact.
But you would have no incentive to do that if I take this patch now :)
Understood.
Ira
--
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 v3 13/23 staging/rdma/hfi1: Wrong cast breaks desired pointer arithmetic
In reply to a message not in the archiveFrom: Mitko Haralanov <[email protected]>
The address being mapped into a process's memory for notification events was improperly calculated due to cast that was happening too early. dd->events is a pointer and should have been casted to unsigned long after the pointer arithmetic was done, not before.
As a result, processes were looking at the wrong place and not seeing their notification events.
--- drivers/staging/rdma/hfi1/file_ops.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/staging/rdma/hfi1/file_ops.c +3 -3
@@ -607,9 +607,9 @@ static int hfi1_file_mmap(struct file *fp, struct vm_area_struct *vma)* Use the page where this context's flags are. User level * knows where it's own bitmap is within the page. */ - memaddr = ((unsigned long )dd->events + - ((uctxt->ctxt - dd->first_user_ctxt) * -HFI1_MAX_SHARED_CTXTS )) &PAGE_MASK ; + memaddr = (unsigned long )(dd->events + + ((uctxt->ctxt - dd->first_user_ctxt) * +HFI1_MAX_SHARED_CTXTS )) &PAGE_MASK ; memlen =PAGE_SIZE ;/* * v3.7 removes VM_RESERVED but the effect is kept by
Signature · 6 lines
1.8.2 -- 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 v3 15/23 staging/rdma/hfi1: Allow tuning of SDMA interrupt rate
In reply to a message not in the archiveFrom: Mitko Haralanov <[email protected]>
The SDMA engines were configured to generate progress interrupts every time they processed N/2 descriptors (where N is the size of the descriptor queue). This interval was too infrequent, leading to degraded performance.
This commit adds a module parameter, as well as a recommended default, which allows for the tuning of the interrupt frequency.
---
Change from v2:
Squash in a patch with a recommended default value of 64.
drivers/staging/rdma/hfi1/sdma.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-)
drivers/staging/rdma/hfi1/sdma.c +9 -1
@@ -66,6 +66,7 @@/* must be a power of 2 >= 64 <= 32768 */ #define SDMA_DESCQ_CNT 1024 +#define SDMA_DESC_INTR 64#define INVALID_TAIL 0xffffstatic uint sdma_descq_cnt =SDMA_DESCQ_CNT ;
@@ -80,6 +81,10 @@ uint mod_num_sdma;module_param_named (num_sdma, mod_num_sdma, uint,S_IRUGO );MODULE_PARM_DESC (num_sdma,"Set max number SDMA engines to use" ); +static uint sdma_desct_intr =SDMA_DESC_INTR ; +module_param_named (desct_intr, sdma_desct_intr, uint,S_IRUGO |S_IWUSR ); +MODULE_PARM_DESC (desct_intr,"Number of SDMA descriptor before interrupt" ); +#define SDMA_WAIT_BATCH_SIZE 20/* max wait time for a SDMA engine to indicate it has halted */ #define SDMA_ERR_HALT_TIMEOUT 10/* ms */
@@ -1046,6 +1051,9 @@ int sdma_init(struct hfi1_devdata *dd, u8 port)return -ENOMEM ; idle_cnt =ns_to_cclock (dd, idle_cnt); +if (!sdma_desct_intr) + sdma_desct_intr =SDMA_DESC_INTR ; +/* Allocate memory for SendDMA descriptor FIFOs */ for (this_idx =0 ; this_idx < num_engines; ++this_idx) { sde = &dd->per_sdma[this_idx];
@@ -1548,7 +1556,7 @@ void sdma_engine_interrupt(struct sdma_engine *sde, u64 status) {trace_hfi1_sdma_engine_interrupt (sde, status);write_seqlock (&sde->head_lock); -sdma_set_desc_cnt (sde, sde->descq_cnt /2 ); +sdma_set_desc_cnt (sde, sdma_desct_intr);sdma_make_progress (sde, status);write_sequnlock (&sde->head_lock); }
Signature · 6 lines
1.8.2 -- 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 v3 18/23 staging/rdma/hfi1: Thread the receive interrupt.
In reply to a message not in the archiveFrom: Dean Luick <[email protected]>
When under heavy load, the receive interrupt handler can run too long with IRQs disabled. Add a mixed-mode threading scheme. Initially process packets in the handler for quick responses (latency). If there are too many packets to process move to a thread to continue (bandwidth).
--- drivers/staging/rdma/hfi1/chip.c | 104 +++++++++++++++++++++++++++++++++---- drivers/staging/rdma/hfi1/driver.c | 72 ++++++++++++++----------- drivers/staging/rdma/hfi1/hfi.h | 20 +++++-- drivers/staging/rdma/hfi1/sdma.c | 4 +- 4 files changed, 154 insertions(+), 46 deletions(-)
drivers/staging/rdma/hfi1/chip.c +95 -9
@@ -4426,7 +4426,7 @@ static void is_rcv_avail_int(struct hfi1_devdata *dd, unsigned int source) rcd = dd->rcd[source];if (rcd) {if (source < dd->first_user_ctxt) - rcd->do_interrupt (rcd); + rcd->do_interrupt (rcd,0 );else handle_user_interrupt (rcd);return ;/* OK */
@@ -4592,23 +4592,106 @@ static irqreturn_t sdma_interrupt(int irq, void *data) }/* -* NOTE: this routine expects to be on its own MSI-X interrupt. If -* multiple receive contexts share the same MSI-X interrupt, then this -* routine must check for who received it. +* Clear the receive interrupt, forcing the write and making sure +* we have data from the chip, pushing everything in front of it +* back to the host. +*/ +static inline void clear_recv_intr (struct hfi1_ctxtdata *rcd) +{ +struct hfi1_devdata *dd = rcd->dd; +u32 addr =CCE_INT_CLEAR + (8 * rcd->ireg); + +mmiowb ();/* make sure everything before is written */ +write_csr (dd, addr, rcd->imask); +/* force the above write on the chip and get a value back */ + (void )read_csr (dd, addr); +} + +/* force the receive interrupt */ +static inline void force_recv_intr (struct hfi1_ctxtdata *rcd) +{ +write_csr (rcd->dd,CCE_INT_FORCE + (8 * rcd->ireg), rcd->imask); +} + +/* return non-zero if a packet is present */ +static inline int check_packet_present (struct hfi1_ctxtdata *rcd) +{ +if (!HFI1_CAP_IS_KSET (DMA_RTAIL )) +return (rcd->seq_cnt == +rhf_rcv_seq (rhf_to_cpu (get_rhf_addr (rcd)))); + +/* else is RDMA rtail */ +return (rcd->head !=get_rcvhdrtail (rcd)); +} + +/* +* Receive packet IRQ handler. This routine expects to be on its own IRQ. +* This routine will try to handle packets immediately (latency), but if +* it finds too many, it will invoke the thread handler (bandwitdh). The +* chip receive interupt is *not* cleared down until this or the thread (if +* invoked) is finished. The intent is to avoid extra interrupts while we +* are processing packets anyway. */ static irqreturn_t receive_context_interrupt (int irq,void *data) {struct hfi1_ctxtdata *rcd = data;struct hfi1_devdata *dd = rcd->dd; +int disposition; +int present;trace_hfi1_receive_interrupt (dd, rcd->ctxt);this_cpu_inc (*dd->int_counter); -/* clear the interrupt */ -write_csr (rcd->dd,CCE_INT_CLEAR + (8 *rcd->ireg), rcd->imask); +/* receive interrupt remains blocked while processing packets */ + disposition = rcd->do_interrupt (rcd,0 ); -/* handle the interrupt */ - rcd->do_interrupt (rcd); +/* +* Too many packets were seen while processing packets in this +* IRQ handler. Invoke the handler thread. The receive interrupt +* remains blocked. +*/ +if (disposition ==RCV_PKT_LIMIT ) +return IRQ_WAKE_THREAD ; + +/* +* The packet processor detected no more packets. Clear the receive +* interrupt and recheck for a packet packet that may have arrived +* after the previous check and interrupt clear. If a packet arrived, +* force another interrupt. +*/ +clear_recv_intr (rcd); + present =check_packet_present (rcd); +if (present) +force_recv_intr (rcd); + +return IRQ_HANDLED ; +} + +/* +* Receive packet thread handler. This expects to be invoked with the +* receive interrupt still blocked. +*/ +static irqreturn_t receive_context_thread (int irq,void *data) +{ +struct hfi1_ctxtdata *rcd = data; +int present; + +/* receive interrupt is still blocked from the IRQ handler */ + (void )rcd->do_interrupt (rcd,1 ); + +/* +* The packet processor will only return if it detected no more +* packets. Hold IRQs here so we can safely clear the interrupt and +* recheck for a packet that may have arrived after the previous +* check and the interrupt clear. If a packet arrived, force another +* interrupt. +*/ +local_irq_disable (); +clear_recv_intr (rcd); + present =check_packet_present (rcd); +if (present) +force_recv_intr (rcd); +local_irq_enable ();return IRQ_HANDLED ; }
@@ -8861,6 +8944,7 @@ static int request_msix_irqs(struct hfi1_devdata *dd)struct hfi1_msix_entry *me = &dd->msix_entries[i];const char *err_info;irq_handler_t handler; +irq_handler_t thread =NULL ;void *arg;int idx;struct hfi1_ctxtdata *rcd =NULL ;
@@ -8897,6 +8981,7 @@ static int request_msix_irqs(struct hfi1_devdata *dd) rcd->imask = ((u64 )1 ) << ((IS_RCVAVAIL_START +idx) %64 ); handler = receive_context_interrupt; + thread = receive_context_thread; arg = rcd;snprintf (me->name,sizeof (me->name),DRIVER_NAME "_%d kctxt%d" , dd->unit, idx);
@@ -8915,7 +9000,8 @@ static int request_msix_irqs(struct hfi1_devdata *dd)/* make sure the name is terminated */ me->name[sizeof (me->name)-1 ] =0 ; - ret =request_irq (me->msix.vector, handler,0 , me->name, arg); + ret =request_threaded_irq (me->msix.vector, handler, thread,0 , + me->name, arg);if (ret) { dd_dev_err(dd, "unable to allocate %s interrupt, vector %d, index %d, err %d\n",
drivers/staging/rdma/hfi1/driver.c +41 -31
183 lines not on this page · raw message
drivers/staging/rdma/hfi1/hfi.h +16 -4
@@ -313,7 +313,7 @@ struct hfi1_ctxtdata {* be valid. Worst case is we process an extra interrupt and up to 64 * packets with the wrong interrupt handler. */ -void (*do_interrupt)(struct hfi1_ctxtdata *rcd); +int (*do_interrupt)(struct hfi1_ctxtdata *rcd,int threaded); };/*
@@ -1151,9 +1151,21 @@ void hfi1_init_pportdata(struct pci_dev *, struct hfi1_pportdata *, struct hfi1_devdata *, u8, u8);void hfi1_free_ctxtdata (struct hfi1_devdata *,struct hfi1_ctxtdata *); -void handle_receive_interrupt (struct hfi1_ctxtdata *); -void handle_receive_interrupt_nodma_rtail (struct hfi1_ctxtdata *rcd); -void handle_receive_interrupt_dma_rtail (struct hfi1_ctxtdata *rcd); +int handle_receive_interrupt (struct hfi1_ctxtdata *,int ); +int handle_receive_interrupt_nodma_rtail (struct hfi1_ctxtdata *,int ); +int handle_receive_interrupt_dma_rtail (struct hfi1_ctxtdata *,int ); + +/* receive packet handler dispositions */ +#define RCV_PKT_OK 0x0/* keep going */ +#define RCV_PKT_LIMIT 0x1/* stop, hit limit, start thread */ +#define RCV_PKT_DONE 0x2/* stop, no more packets detected */ + +/* calculate the current RHF address */ +static inline __le32 *get_rhf_addr (struct hfi1_ctxtdata *rcd) +{ +return (__le32 *)rcd->rcvhdrq + rcd->head + rcd->dd->rhf_offset; +} +int hfi1_reset_device (int );/* return the driver's idea of the logical OPA port state */
drivers/staging/rdma/hfi1/sdma.c +2 -2
@@ -2098,9 +2098,9 @@ unlock_noconn: tx->sn = sde->tail_sn++;trace_hfi1_sdma_in_sn (sde, tx->sn);#endif -spin_lock_irqsave (&sde->flushlist_lock, flags); +spin_lock (&sde->flushlist_lock);list_add_tail (&tx->list, &sde->flushlist); -spin_unlock_irqrestore (&sde->flushlist_lock, flags); +spin_unlock (&sde->flushlist_lock);if (wait) { wait->tx_count++; wait->count += tx->num_desc;
Signature · 6 lines
1.8.2 -- 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 v3 19/23 staging/rdma/hfi: modify workqueue for parallelism
In reply to a message not in the archiveFrom: Mike Marciniszyn <[email protected]>
The workqueue is currently single threaded per port which for a small number of SDMA engines is ok.
For hfi1, the there are up to 16 SDMA engines that can be fed descriptors in parallel.
This patch:
- Converts to use alloc_workqueue
- Changes the workqueue limit from 1 to num_sdma
- Makes the queue WQ_CPU_INTENSIVE and WQ_HIGHPRI
- The sdma_engine now has a cpu that is initialized as the MSI-X vectors are setup
- Adjusts the post send logic to call a new scheduler that doesn't get the s_lock
- The new and old workqueue schedule now pass a cpu
- post send now uses the new scheduler
- RC/UC QPs now pre-compute the sc, sde
- The sde wq is eliminated since the new hfi1_wq is multi-threaded
--- drivers/staging/rdma/hfi1/chip.c | 1 + drivers/staging/rdma/hfi1/init.c | 13 +++++------ drivers/staging/rdma/hfi1/iowait.h | 6 +++-- drivers/staging/rdma/hfi1/qp.c | 47 +++++++++++++++++++++++++++++++++----- drivers/staging/rdma/hfi1/qp.h | 38 +++++++++++++++++++++++++++++- drivers/staging/rdma/hfi1/ruc.c | 30 ++---------------------- drivers/staging/rdma/hfi1/sdma.c | 8 ++++--- drivers/staging/rdma/hfi1/sdma.h | 8 ++++--- drivers/staging/rdma/hfi1/ud.c | 1 + drivers/staging/rdma/hfi1/verbs.c | 34 ++++++--------------------- drivers/staging/rdma/hfi1/verbs.h | 6 ++--- 11 files changed, 111 insertions(+), 81 deletions(-)
drivers/staging/rdma/hfi1/chip.c +1 -0
@@ -9021,6 +9021,7 @@ static int request_msix_irqs(struct hfi1_devdata *dd)if (handler == sdma_interrupt) {dd_dev_info (dd,"sdma engine %d cpu %d\n" , sde->this_idx, sdma_cpu); + sde->cpu = sdma_cpu;cpumask_set_cpu (sdma_cpu, dd->msix_entries[i].mask); sdma_cpu =cpumask_next (sdma_cpu, def);if (sdma_cpu >= nr_cpu_ids)
drivers/staging/rdma/hfi1/init.c +6 -7
@@ -601,20 +601,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) {
drivers/staging/rdma/hfi1/iowait.h +4 -2
@@ -150,12 +150,14 @@ static inline void iowait_init(* iowait_schedule() - initialize wait structure * @wait: wait struct to schedule * @wq: workqueue for schedule +* @cpu: cpu */ static inline void iowait_schedule (struct iowait *wait, -struct workqueue_struct *wq) +struct workqueue_struct *wq, +int cpu) { -queue_work (wq, &wait->iowork); +queue_work_on (cpu, wq, &wait->iowork); }/**
drivers/staging/rdma/hfi1/qp.c +41 -6
95 lines not on this page · raw message
drivers/staging/rdma/hfi1/qp.h +37 -1
@@ -128,7 +128,6 @@ static inline void clear_ahg(struct hfi1_qp *qp)if (qp->s_sde && qp->s_ahgidx >=0 )sdma_ahg_free (qp->s_sde, qp->s_ahgidx); qp->s_ahgidx =-1 ; - qp->s_sde =NULL ; }/**
@@ -247,4 +246,41 @@ void qp_iter_print(struct seq_file *s, struct qp_iter *iter);*/ void qp_comm_est (struct hfi1_qp *qp); +/** +* _hfi1_schedule_send - schedule progress +* @qp: the QP +* +* This schedules qp progress w/o regard to the s_flags. +* +* It is only used in the post send, which doesn't hold +* the s_lock. +*/ +static inline void _hfi1_schedule_send (struct hfi1_qp *qp) +{ +struct hfi1_ibport *ibp = +to_iport (qp->ibqp.device, qp->port_num); +struct hfi1_pportdata *ppd =ppd_from_ibp (ibp); +struct hfi1_devdata *dd =dd_from_ibdev (qp->ibqp.device); + +iowait_schedule (&qp->s_iowait, ppd->hfi1_wq, + qp->s_sde ? + qp->s_sde->cpu : +cpumask_first (cpumask_of_node (dd->assigned_node_id))); +} + +/** +* hfi1_schedule_send - schedule progress +* @qp: the QP +* +* This schedules qp progress and caller should hold +* the s_lock. +*/ +static inline void hfi1_schedule_send (struct hfi1_qp *qp) +{ +if (hfi1_send_ok (qp)) +_hfi1_schedule_send (qp); +} + +void hfi1_migrate_qp (struct hfi1_qp *qp); +#endif /* _QP_H */
drivers/staging/rdma/hfi1/ruc.c +2 -28
@@ -241,26 +241,6 @@ bail:return ret; } -/* -* Switch to alternate path. -* The QP s_lock should be held and interrupts disabled. -*/ -void hfi1_migrate_qp (struct hfi1_qp *qp) -{ -struct ib_event ev; - - qp->s_mig_state =IB_MIG_MIGRATED ; - qp->remote_ah_attr = qp->alt_ah_attr; - qp->port_num = qp->alt_ah_attr.port_num; - qp->s_pkey_index = qp->s_alt_pkey_index; - qp->s_flags |=HFI1_S_AHG_CLEAR ; - - ev.device = qp->ibqp.device; - ev.element.qp = &qp->ibqp; - ev.event =IB_EVENT_PATH_MIG ; - qp->ibqp.event_handler (&ev, qp->ibqp.qp_context); -} -static __be64 get_sguid (struct hfi1_ibport *ibp,unsigned index) {if (!index) {
@@ -714,11 +694,8 @@ static inline void build_ahg(struct hfi1_qp *qp, u32 npsn)clear_ahg (qp);if (!(qp->s_flags &HFI1_S_AHG_VALID )) {/* first middle that needs copy */ -if (qp->s_ahgidx <0 ) { -if (!qp->s_sde) - qp->s_sde =qp_to_sdma_engine (qp, qp->s_sc); +if (qp->s_ahgidx <0 ) qp->s_ahgidx =sdma_ahg_alloc (qp->s_sde); - }if (qp->s_ahgidx >=0 ) { qp->s_ahgpsn = npsn; qp->s_hdr->tx_flags |=SDMA_TXREQ_F_AHG_COPY ;
@@ -761,7 +738,6 @@ void hfi1_make_ruc_header(struct hfi1_qp *qp, struct hfi1_other_headers *ohdr,u16 lrh0;u32 nwords;u32 extra_bytes; -u8 sc5;u32 bth1;/* Construct the header. */
@@ -775,9 +751,7 @@ void hfi1_make_ruc_header(struct hfi1_qp *qp, struct hfi1_other_headers *ohdr, lrh0 =HFI1_LRH_GRH ; middle =0 ; } - sc5 = ibp->sl_to_sc[qp->remote_ah_attr.sl]; - lrh0 |= (sc5 &0xf ) <<12 | (qp->remote_ah_attr.sl &0xf ) <<4 ; - qp->s_sc = sc5; + lrh0 |= (qp->s_sc &0xf ) <<12 | (qp->remote_ah_attr.sl &0xf ) <<4 ;/* * reset s_hdr/AHG fields *
drivers/staging/rdma/hfi1/sdma.c +5 -3
@@ -778,18 +778,19 @@ struct sdma_engine *sdma_select_engine_vl(struct sdma_engine *rval;if (WARN_ON (vl >8 )) -return NULL ; +return &dd->per_sdma[0 ];rcu_read_lock (); m =rcu_dereference (dd->sdma_map);if (unlikely (!m)) {rcu_read_unlock (); -return NULL ; +return &dd->per_sdma[0 ]; } e = m->map[vl & m->mask]; rval = e->sde[selector & e->mask];rcu_read_unlock (); + rval = !rval ? &dd->per_sdma[0 ] : rval;trace_hfi1_sdma_engine_select (dd, selector, vl, rval->this_idx);return rval; }
@@ -1876,7 +1877,7 @@ static void dump_sdma_state(struct sdma_engine *sde) }#define SDE_FMT \ - "SDE %u STE %s C 0x%llx S 0x%016llx E 0x%llx T(HW) 0x%llx T(SW) 0x%x H(HW) 0x%llx H(SW) 0x%x H(D) 0x%llx DM 0x%llx GL 0x%llx R 0x%llx LIS 0x%llx AHGI 0x%llx TXT %u TXH %u DT %u DH %u FLNE %d DQF %u SLC 0x%llx\n" + "SDE %u CPU %d STE %s C 0x%llx S 0x%016llx E 0x%llx T(HW) 0x%llx T(SW) 0x%x H(HW) 0x%llx H(SW) 0x%x H(D) 0x%llx DM 0x%llx GL 0x%llx R 0x%llx LIS 0x%llx AHGI 0x%llx TXT %u TXH %u DT %u DH %u FLNE %d DQF %u SLC 0x%llx\n"/** * sdma_seqfile_dump_sde() - debugfs dump of sde * @s: seq file
@@ -1896,6 +1897,7 @@ void sdma_seqfile_dump_sde(struct seq_file *s, struct sdma_engine *sde) head = sde->descq_head & sde->sdma_mask; tail =ACCESS_ONCE (sde->descq_tail) & sde->sdma_mask; seq_printf(s, SDE_FMT, sde->this_idx, + sde->cpu, sdma_state_name(sde->state.current_state), (unsigned long long)read_sde_csr(sde, SD(CTRL)), (unsigned long long)read_sde_csr(sde, SD(STATUS)),
drivers/staging/rdma/hfi1/sdma.h +5 -3
@@ -410,8 +410,6 @@ struct sdma_engine {u64 idle_mask;u64 progress_mask;/* private: */ -struct workqueue_struct *wq; -/* private: */ volatile __le64 *head_dma;/* DMA'ed by chip */ /* private: */ dma_addr_t head_phys;
@@ -426,6 +424,8 @@ struct sdma_engine {u32 sdma_mask;/* private */ struct sdma_state state; +/* private */ +int cpu;/* private: */ u8 sdma_shift;/* private: */
@@ -990,7 +990,9 @@ static inline void sdma_iowait_schedule(struct sdma_engine *sde, struct iowait *wait) { - iowait_schedule(wait, sde->wq); + struct hfi1_pportdata *ppd = sde->dd->pport; + +iowait_schedule (wait, ppd->hfi1_wq, sde->cpu); }/* for use by interrupt handling */
drivers/staging/rdma/hfi1/ud.c +1 -0
@@ -383,6 +383,7 @@ int hfi1_make_ud_req(struct hfi1_qp *qp) lrh0 |= (sc5 &0xf ) <<12 ; qp->s_sc = sc5; } + qp->s_sde =qp_to_sdma_engine (qp, qp->s_sc); qp->s_hdr->ibh.lrh[0 ] =cpu_to_be16 (lrh0); qp->s_hdr->ibh.lrh[1 ] =cpu_to_be16 (ah_attr->dlid);/* DEST LID */ qp->s_hdr->ibh.lrh[2] =
drivers/staging/rdma/hfi1/verbs.c +7 -27
@@ -159,6 +159,8 @@ static inline struct hfi1_ucontext *to_iucontext(struct ib_ucontext return container_of(ibucontext, struct hfi1_ucontext, ibucontext); } +static inline void _hfi1_schedule_send (struct hfi1_qp *qp); +/* * Translate ib_wr_opcode into ib_wc_opcode. */
@@ -494,9 +496,9 @@ static int post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, nreq++; } bail: -if (nreq && !call_send) -hfi1_schedule_send (qp);spin_unlock_irqrestore (&qp->s_lock, flags); +if (nreq && !call_send) +_hfi1_schedule_send (qp);if (nreq && call_send)hfi1_do_send (&qp->s_iowait.iowork);return err;
@@ -994,7 +996,6 @@ int hfi1_verbs_send_dma(struct hfi1_qp *qp, struct ahg_ib_header *ahdr,struct verbs_txreq *tx;struct sdma_txreq *stx;u64 pbc_flags =0 ; -struct sdma_engine *sde;u8 sc5 = qp->s_sc;int ret;
@@ -1015,12 +1016,7 @@ int hfi1_verbs_send_dma(struct hfi1_qp *qp, struct ahg_ib_header *ahdr,if (IS_ERR (tx)) goto bail_tx; -if (!qp->s_hdr->sde) { - tx->sde = sde =qp_to_sdma_engine (qp, sc5); -if (!sde) - goto bail_no_sde; - }else - tx->sde = sde = qp->s_hdr->sde; + tx->sde = qp->s_sde;if (likely (pbc ==0 )) {u32 vl =sc_to_vlt (dd_from_ibdev (qp->ibqp.device), sc5);
@@ -1035,17 +1031,15 @@ int hfi1_verbs_send_dma(struct hfi1_qp *qp, struct ahg_ib_header *ahdr,if (qp->s_rdma_mr) qp->s_rdma_mr =NULL ; tx->hdr_dwords = hdrwords +2 ; - ret =build_verbs_tx_desc (sde, ss, len, tx, ahdr, pbc); + ret =build_verbs_tx_desc (tx->sde, ss, len, tx, ahdr, pbc);if (unlikely (ret)) goto bail_build;trace_output_ibhdr (dd_from_ibdev (qp->ibqp.device), &ahdr->ibh); - ret =sdma_send_txreq (sde, &qp->s_iowait, &tx->txreq); + ret =sdma_send_txreq (tx->sde, &qp->s_iowait, &tx->txreq);if (unlikely (ret == -ECOMM )) goto bail_ecomm;return ret; -bail_no_sde: -hfi1_put_txreq (tx); bail_ecomm:/* The current one got "sent" */ return 0 ;
@@ -2120,20 +2114,6 @@ void hfi1_unregister_ib_device(struct hfi1_devdata *dd)vfree (dev->lk_table.table); } -/* -* This must be called with s_lock held. -*/ -void hfi1_schedule_send (struct hfi1_qp *qp) -{ -if (hfi1_send_ok (qp)) { -struct hfi1_ibport *ibp = -to_iport (qp->ibqp.device, qp->port_num); -struct hfi1_pportdata *ppd =ppd_from_ibp (ibp); - -iowait_schedule (&qp->s_iowait, ppd->hfi1_wq); - } -} -void hfi1_cnp_rcv (struct hfi1_packet *packet) {struct hfi1_ibport *ibp = &packet->rcd->ppd->ibport_data;
drivers/staging/rdma/hfi1/verbs.h +2 -4
@@ -436,7 +436,8 @@ struct hfi1_qp {struct hfi1_swqe *s_wq;/* send work queue */ struct hfi1_mmap_info *ip;struct ahg_ib_header *s_hdr;/* next packet header to send */ -u8 s_sc;/* SC[0..4] for next packet */ +/* sc for UC/RC QPs - based on ah for UD */ +u8 s_sc;unsigned long timeout_jiffies;/* computed from timeout */ enum ib_mtu path_mtu;
@@ -841,7 +842,6 @@ static inline int hfi1_send_ok(struct hfi1_qp *qp)/* * This must be called with s_lock held. */ -void hfi1_schedule_send (struct hfi1_qp *qp);void hfi1_bad_pqkey (struct hfi1_ibport *ibp,__be16 trap_num,u32 key,u32 sl,u32 qp1,u32 qp2,__be16 lid1,__be16 lid2);void hfi1_cap_mask_chg (struct hfi1_ibport *ibp);
@@ -1071,8 +1071,6 @@ int hfi1_mmap(struct ib_ucontext *context, struct vm_area_struct *vma);int hfi1_get_rwqe (struct hfi1_qp *qp,int wr_id_only); -void hfi1_migrate_qp (struct hfi1_qp *qp); -int hfi1_ruc_check_hdr (struct hfi1_ibport *ibp,struct hfi1_ib_header *hdr,int has_grh,struct hfi1_qp *qp,u32 bth0);
Signature · 6 lines
1.8.2 -- 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
Greg KH
maintainerRe: [PATCH v3 19/23] staging/rdma/hfi: modify workqueue for parallelism
Quoted 8 lines · On Mon, Oct 26, 2015 at 10:28:45AM -0400, [email protected] wrote:
From: Mike Marciniszyn <[email protected]>
The workqueue is currently single threaded per port which for a small number of SDMA engines is ok.
For hfi1, the there are up to 16 SDMA engines that can be fed descriptors in parallel.
Quoted 14 lines
This patch:
- Converts to usealloc_workqueue
- Changes the workqueue limit from 1 tonum_sdma
- Makes the queueWQ_CPU_INTENSIVEandWQ_HIGHPRI
- Thesdma_enginenow has a cpu that is initialized as the MSI-X vectors are setup
- Adjusts the post send logic to call a new scheduler that doesn't get thes_lock
- The new and old workqueue schedule now pass a cpu
- post send now uses the new scheduler
- RC/UC QPs now pre-compute the sc, sde
- The sde wq is eliminated since the newhfi1_wqis multi-threaded
When you have to start enumerating all of the different things that your patch does, that's a huge hint that you need to break it up into smaller pieces.
Please break this up, it's not acceptable as-is.
thanks,
greg k-h
PATCH v3 20/23 staging/rdma/hfi1: Load SBus firmware once per ASIC
In reply to a message not in the archiveFrom: Easwar Hariharan <[email protected]>
Using fw_sbus_load to control SBus firmware load doesn't scale across multiple HFI1 cards in a single system. This patch ensures that the SBus firmware is loaded once per ASIC.
--- drivers/staging/rdma/hfi1/firmware.c | 31 ++++++++----------------------- drivers/staging/rdma/hfi1/pcie.c | 10 ++++++---- 2 files changed, 14 insertions(+), 27 deletions(-)
drivers/staging/rdma/hfi1/firmware.c +8 -23
@@ -1236,35 +1236,20 @@ int load_firmware(struct hfi1_devdata *dd) {int ret; -if (fw_sbus_load || fw_fabric_serdes_load) { +if (fw_fabric_serdes_load) { ret =acquire_hw_mutex (dd);if (ret)return ret;set_sbus_fast_mode (dd); -/* -* The SBus contains part of the fabric firmware and so must -* also be downloaded. -*/ -if (fw_sbus_load) { -turn_off_spicos (dd,SPICO_SBUS ); - ret =load_sbus_firmware (dd, &fw_sbus); -if (ret) - goto clear; - fw_sbus_load =0 ; - } +set_serdes_broadcast (dd, all_fabric_serdes_broadcast, + fabric_serdes_broadcast[dd->hfi1_id], + fabric_serdes_addrs[dd->hfi1_id], +NUM_FABRIC_SERDES ); +turn_off_spicos (dd,SPICO_FABRIC ); + ret =load_fabric_serdes_firmware (dd, &fw_fabric); -if (fw_fabric_serdes_load) { -set_serdes_broadcast (dd, all_fabric_serdes_broadcast, - fabric_serdes_broadcast[dd->hfi1_id], - fabric_serdes_addrs[dd->hfi1_id], -NUM_FABRIC_SERDES ); -turn_off_spicos (dd,SPICO_FABRIC ); - ret =load_fabric_serdes_firmware (dd, &fw_fabric); - } - -clear:clear_sbus_fast_mode (dd);release_hw_mutex (dd);if (ret)
@@ -1583,7 +1568,7 @@ int load_pcie_firmware(struct hfi1_devdata *dd)/* both firmware loads below use the SBus */ set_sbus_fast_mode (dd); -if (fw_sbus_load) { +if (fw_sbus_load && (dd->flags &HFI1_DO_INIT_ASIC )) {turn_off_spicos (dd,SPICO_SBUS ); ret =load_sbus_firmware (dd, &fw_sbus);if (ret)
drivers/staging/rdma/hfi1/pcie.c +6 -4
@@ -947,15 +947,16 @@ int do_pcie_gen3_transition(struct hfi1_devdata *dd) } retry: +if (therm) { -/* toggle SPICO_ENABLE to get back to the state -just after the firmware load */ +/* +* toggle SPICO_ENABLE to get back to the state +* just after the firmware load +*/ sbus_request (dd,SBUS_MASTER_BROADCAST ,0x01 ,WRITE_SBUS_RECEIVER ,0x00000040 );sbus_request (dd,SBUS_MASTER_BROADCAST ,0x01 ,WRITE_SBUS_RECEIVER ,0x00000140 ); -dd_dev_info (dd,"%s: toggle SPICO_ENABLE to reset the bus\n" , - __func__); }/* step 3: download SBus Master firmware */
@@ -1198,6 +1199,7 @@ retry:/* clear the DC reset */ write_csr (dd,CCE_DC_CTRL ,0 ); +/* Set the LED off */ if (is_a0 (dd))setextled (dd,0 );
Signature · 6 lines
1.8.2 -- 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 v3 21/23 staging/rdma/hfi1: Add unit # to verbs txreq cache name
In reply to a message not in the archiveFrom: Jubin John <[email protected]>
The name used to create the verbs txreq cache was not qualified with the unit number. This causes a panic when destroying the cache on a dual HFI systems. Create a unique name with the unit number with this patch
--- drivers/staging/rdma/hfi1/verbs.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
drivers/staging/rdma/hfi1/verbs.c +6 -1
@@ -129,6 +129,9 @@ static void verbs_sdma_complete(int status, int drained); +/* Length of buffer to create verbs txreq cache name */ +#define TXREQ_NAME_LEN 24 +/* * Note that it is OK to post send work requests in the SQE and ERR * states; hfi1_do_send() will process them and generate error
@@ -1899,6 +1902,7 @@ int hfi1_register_ib_device(struct hfi1_devdata *dd)int ret;size_t lcpysz =IB_DEVICE_NAME_MAX ;u16 descq_cnt; +char buf[TXREQ_NAME_LEN ]; ret =hfi1_qp_init (dev);if (ret)
@@ -1952,8 +1956,9 @@ int hfi1_register_ib_device(struct hfi1_devdata *dd) descq_cnt =sdma_get_descq_cnt (); +snprintf (buf,sizeof (buf),"hfi1_%u_vtxreq_cache" , dd->unit);/* SLAB_HWCACHE_ALIGN for AHG */ - dev->verbs_txreq_cache =kmem_cache_create ("hfi1_vtxreq_cache" , + dev->verbs_txreq_cache =kmem_cache_create (buf,sizeof (struct verbs_txreq ),0 ,SLAB_HWCACHE_ALIGN , verbs_txreq_kmem_cache_ctor);
Signature · 6 lines
1.8.2 -- 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 v3 22/23 staging/rdma/hfi1: add additional rc traces
In reply to a message not in the archiveFrom: Mike Marciniszyn <[email protected]>
Add additional rc traces to aid in debugging rc retry logic.
--- drivers/staging/rdma/hfi1/rc.c | 4 ++++ drivers/staging/rdma/hfi1/trace.c | 4 ++-- drivers/staging/rdma/hfi1/trace.h | 48 +++++++++++++++++++++++++++++---------- 3 files changed, 42 insertions(+), 14 deletions(-)
drivers/staging/rdma/hfi1/rc.c +4 -0
@@ -927,6 +927,7 @@ static void rc_timeout(unsigned long arg) ibp->n_rc_timeouts++; qp->s_flags &= ~HFI1_S_TIMER ;del_timer (&qp->s_timer); +trace_hfi1_rc_timeout (qp, qp->s_last_psn +1 );restart_rc (qp, qp->s_last_psn +1 ,1 );hfi1_schedule_send (qp); }
@@ -1442,6 +1443,8 @@ static void rc_rcv_resp(struct hfi1_ibport *ibp,spin_lock_irqsave (&qp->s_lock, flags); +trace_hfi1_rc_ack (qp, psn); +/* Ignore invalid responses. */ if (cmp_psn (psn, qp->s_next_psn) >=0 ) goto ack_done;
@@ -1630,6 +1633,7 @@ static noinline int rc_rcv_error(struct hfi1_other_headers *ohdr, void *data,u8 i, prev;int old_req; +trace_hfi1_rc_rcv_error (qp, psn);if (diff >0 ) {/* * Packet sequence error.
drivers/staging/rdma/hfi1/trace.c +2 -2
@@ -126,13 +126,13 @@ const char *parse_everbs_hdrs(case OP (RC ,ACKNOWLEDGE ):trace_seq_printf (p,AETH_PRN ,be32_to_cpu (eh->aeth) >>24 , -be32_to_cpu (eh->aeth) &HFI1_QPN_MASK ); +be32_to_cpu (eh->aeth) &HFI1_MSN_MASK );break ;/* aeth + atomicacketh */ case OP (RC ,ATOMIC_ACKNOWLEDGE ):trace_seq_printf (p,AETH_PRN " " ATOMICACKETH_PRN , (be32_to_cpu (eh->at.aeth) >>24 ) &0xff , -be32_to_cpu (eh->at.aeth) &HFI1_QPN_MASK , +be32_to_cpu (eh->at.aeth) &HFI1_MSN_MASK , (unsigned long long )ib_u64_get (eh->at.atomic_ack_eth));break ;/* atomiceth */
drivers/staging/rdma/hfi1/trace.h +36 -12
73 lines not on this page · raw message
Signature · 6 lines
1.8.2 -- 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 v3 23/23 staging/rdma/hfi1: Update driver version string to 0.9-294
In reply to a message not in the archiveFrom: Jubin John <[email protected]>
--- drivers/staging/rdma/hfi1/common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/staging/rdma/hfi1/common.h +1 -1
@@ -205,7 +205,7 @@* to the driver itself, not the software interfaces it supports. */ #ifndef HFI1_DRIVER_VERSION_BASE -#define HFI1_DRIVER_VERSION_BASE "0.9-248" +#define HFI1_DRIVER_VERSION_BASE "0.9-294"#endif /* create the final driver version string */
Signature · 6 lines
1.8.2 -- 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): 1445869729-7507-24-git-send-email-ira.weiny-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org
Re: [PATCH v3 23/23] staging/rdma/hfi1: Update driver version string to 0.9-294
Quoted 13 lines · On Mon, Oct 26, 2015 at 10:28:49AM -0400…
From: Jubin John <[email protected]>
Signed-off-by Jubin John <[email protected]>Signed-off-by Ira Weiny <[email protected]>--- drivers/staging/rdma/hfi1/common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)drivers/staging/rdma/hfi1/common.h +0
-0
drivers/staging/rdma/hfi1/common.h line 208
Quoted 5 lines
drivers/staging/rdma/hfi1/common.h +1
-1@@ -205,7 +205,7 @@* to the driver itself, not the software interfaces it supports. */ #ifndef HFI1_DRIVER_VERSION_BASE -#define HFI1_DRIVER_VERSION_BASE "0.9-248" +#define HFI1_DRIVER_VERSION_BASE "0.9-294"
Patches like this make no sense at all, please drop it and only use the kernel version. Trust me, it's going to get messy really fast (hint, it already did...)
greg k-h
--
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): [email protected]
Re: [PATCH v3 23/23] staging/rdma/hfi1: Update driver version string to 0.9-294
Quoted 9 lines · Greg KH
Quoted 8 lines · On Mon, Oct 26, 2015 at 10:28:49AM -0400…
From: Jubin John <[email protected]>
Signed-off-by Jubin John <[email protected]>Signed-off-by Ira Weiny <[email protected]>--- drivers/staging/rdma/hfi1/common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
Quoted 13 lines
drivers/staging/rdma/hfi1/common.h line 208
Quoted 10 lines
drivers/staging/rdma/hfi1/common.h +1
-1@@ -205,7 +205,7 @@* to the driver itself, not the software interfaces it supports. */ #ifndef HFI1_DRIVER_VERSION_BASE -#define HFI1_DRIVER_VERSION_BASE "0.9-248" +#define HFI1_DRIVER_VERSION_BASE "0.9-294"Patches like this make no sense at all, please drop it and only use the kernel version.
What do you mean by "only use the kernel version"? Do you mean
#define HFI1_DRIVER_VERSION_BASE UTS_RELEASE
Or just remove the macro entirely?
Quoted 3 lines
Trust me, it's going to get messy really fast (hint, it already did...)
Did I base this on the wrong tree? Not sure how this could have messed you up.
Thanks,
Ira
--
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
Greg KH
maintainerRe: [PATCH v3 23/23] staging/rdma/hfi1: Update driver version string to 0.9-294
Quoted 24 lines · ira.weiny
Quoted 9 lines · Greg KH
Quoted 8 lines · On Mon, Oct 26, 2015 at 10:28:49AM -0400, [email protected] wrote:
From: Jubin John <[email protected]>
Signed-off-by Jubin John <[email protected]>Signed-off-by Ira Weiny <[email protected]>--- drivers/staging/rdma/hfi1/common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)Quoted 13 lines
drivers/staging/rdma/hfi1/common.h line 208
Quoted 10 lines
drivers/staging/rdma/hfi1/common.h +1
-1@@ -205,7 +205,7 @@* to the driver itself, not the software interfaces it supports. */ #ifndef HFI1_DRIVER_VERSION_BASE -#define HFI1_DRIVER_VERSION_BASE "0.9-248" +#define HFI1_DRIVER_VERSION_BASE "0.9-294"Patches like this make no sense at all, please drop it and only use the kernel version.
Quoted 5 lines
What do you mean by "only use the kernel version"? Do you mean
#define
HFI1_DRIVER_VERSION_BASEUTS_RELEASEOr just remove the macro entirely?
Remove it entirely, it's pointless and makes no sense for in-kernel code.
Quoted 4 lines
Quoted 2 lines
Trust me, it's going to get messy really fast (hint, it already did...)
Did I base this on the wrong tree? Not sure how this could have messed you up.
Nope, the patch applied just fine, but think about it, I didn't take all of the patches you sent me, so what exactly does that version number now represent? Hint, absolutely nothing, or even worse, something completely wrong :)
thanks,
greg k-h
PATCH v3 2/23 staging/rdma/hfi1: Fix code to reset ASIC CSRs on FLR
In reply to [email protected]From: Easwar Hariharan <[email protected]>
The ASIC registers were not reset on FLR, and the code to protect the ASIC block against multiple initializations by peer HFIs did not extend to multiple ASICs in a system. This patch addresses this gap.
--- drivers/staging/rdma/hfi1/chip.c | 35 +++++++++++++++-------------------- drivers/staging/rdma/hfi1/firmware.c | 4 ++++ 2 files changed, 19 insertions(+), 20 deletions(-)
drivers/staging/rdma/hfi1/chip.c +15 -20
@@ -9327,8 +9327,6 @@ static void reset_cce_csrs(struct hfi1_devdata *dd)/* set ASIC CSRs to chip reset defaults */ static void reset_asic_csrs (struct hfi1_devdata *dd) { -static DEFINE_MUTEX (asic_mutex); -static int called;int i;/*
@@ -9338,15 +9336,8 @@ static void reset_asic_csrs(struct hfi1_devdata *dd)* a known first load do the reset and blocking all others. */ -/* -* These CSRs should only be reset once - the first one here will -* do the work. Use a mutex so that a non-first caller waits until -* the first is finished before it can proceed. -*/ -mutex_lock (&asic_mutex); -if (called) - goto done; - called =1 ; +if (!(dd->flags &HFI1_DO_INIT_ASIC )) +return ;if (dd->icode !=ICODE_FPGA_EMULATION ) {/* emulation does not have an SBus - leave these alone */
@@ -9366,7 +9357,10 @@ static void reset_asic_csrs(struct hfi1_devdata *dd)for (i =0 ; i <ASIC_NUM_SCRATCH ; i++)write_csr (dd,ASIC_CFG_SCRATCH + (8 * i),0 );write_csr (dd,ASIC_CFG_MUTEX ,0 );/* this will clear it */ + +/* We might want to retain this state across FLR if we ever use it */ write_csr (dd,ASIC_CFG_DRV_STR ,0 ); +write_csr (dd,ASIC_CFG_THERM_POLL_EN ,0 );/* ASIC_STS_THERM read-only */ /* ASIC_CFG_RESET leave alone */
@@ -9413,9 +9407,6 @@ static void reset_asic_csrs(struct hfi1_devdata *dd)/* this also writes a NOP command, clearing paging mode */ write_csr (dd,ASIC_EEP_ADDR_CMD ,0 );write_csr (dd,ASIC_EEP_DATA ,0 ); - -done: -mutex_unlock (&asic_mutex); }/* set MISC CSRs to chip reset defaults */
@@ -9827,6 +9818,7 @@ static void init_chip(struct hfi1_devdata *dd)restore_pci_variables (dd); } +reset_asic_csrs (dd); }else {dd_dev_info (dd,"Resetting CSRs with writes\n" );reset_cce_csrs (dd);
@@ -9837,6 +9829,7 @@ static void init_chip(struct hfi1_devdata *dd) }/* clear the DC reset */ write_csr (dd,CCE_DC_CTRL ,0 ); +/* Set the LED off */ if (is_a0 (dd))setextled (dd,0 );
@@ -10332,7 +10325,7 @@ static void asic_should_init(struct hfi1_devdata *dd) }/** -* Allocate an initialize the device structure for the hfi. +* Allocate and initialize the device structure for the hfi. * @dev: the pci_dev for hfi1_ib device * @ent: pci_device_id struct for this dev *
@@ -10488,6 +10481,12 @@ struct hfi1_devdata *hfi1_init_dd(struct pci_dev *pdev,else if (dd->rcv_intr_timeout_csr ==0 && rcv_intr_timeout) dd->rcv_intr_timeout_csr =1 ; +/* needs to be done before we look for the peer device */ +read_guid (dd); + +/* should this device init the ASIC block? */ +asic_should_init (dd); +/* obtain chip sizes, reset chip CSRs */ init_chip (dd);
@@ -10496,11 +10495,6 @@ struct hfi1_devdata *hfi1_init_dd(struct pci_dev *pdev,if (ret) goto bail_cleanup; -/* needs to be done before we look for the peer device */ -read_guid (dd); - -asic_should_init (dd); -/* read in firmware */ ret =hfi1_firmware_init (dd);if (ret)
@@ -10715,6 +10709,7 @@ static int thermal_init(struct hfi1_devdata *dd)acquire_hw_mutex (dd);dd_dev_info (dd,"Initializing thermal sensor\n" ); +/* Thermal Sensor Initialization */ /* Step 1: Reset the Thermal SBus Receiver */ ret = sbus_request_slow(dd, SBUS_THERMAL, 0x0,
drivers/staging/rdma/hfi1/firmware.c +4 -0
@@ -1614,6 +1614,10 @@ done:*/ void read_guid (struct hfi1_devdata *dd) { +/* Take the DC out of reset to get a valid GUID value */ +write_csr (dd,CCE_DC_CTRL ,0 ); + (void )read_csr (dd,CCE_DC_CTRL ); + dd->base_guid =read_csr (dd,DC_DC8051_CFG_LOCAL_GUID );dd_dev_info (dd,"GUID %llx" , (unsigned long long )dd->base_guid);
Signature · 1 line
1.8.2
PATCH v3 4/23 staging/rdma/hfi1: Prevent host software lock up
In reply to [email protected]From: Vennila Megavannan <[email protected]>
If packets stop egressing the hardware link, software can lock up.
Implement a timeout for send context halt recovery. This patch increases the timeout for packet egress to 500 us and timer resets to zero if the packet occupancy changes. Also we bounce the link on time out.
--- drivers/staging/rdma/hfi1/pio.c | 14 +++++++++++--- drivers/staging/rdma/hfi1/sdma.c | 15 ++++++++++++--- 2 files changed, 23 insertions(+), 6 deletions(-)
drivers/staging/rdma/hfi1/pio.c +11 -3
@@ -922,10 +922,12 @@ void sc_disable(struct send_context *sc)static void sc_wait_for_packet_egress (struct send_context *sc,int pause) {struct hfi1_devdata *dd = sc->dd; -u64 reg; +u64 reg =0 ; +u64 reg_prev;u32 loop =0 ;while (1 ) { + reg_prev = reg; reg =read_csr (dd, sc->hw_context *8 +SEND_EGRESS_CTXT_STATUS );/* done if egress is stopped */
@@ -934,11 +936,17 @@ static void sc_wait_for_packet_egress(struct send_context *sc, int pause) reg =packet_occupancy (reg);if (reg ==0 )break ; -if (loop >100 ) { +/* counter is reset if occupancy count changes */ +if (reg != reg_prev) + loop =0 ; +if (loop >500 ) { +/* timed out - bounce the link */ dd_dev_err (dd, -"%s: context %u(%u) timeout waiting for packets to egress, remaining count %u\n" , +"%s: context %u(%u) timeout waiting for packets to egress, remaining count %u, bouncing link\n" , __func__, sc->sw_index, sc->hw_context, (u32 )reg); +queue_work (dd->pport->hfi1_wq, + &dd->pport->link_bounce_work);break ; } loop++;
drivers/staging/rdma/hfi1/sdma.c +12 -3
@@ -303,17 +303,26 @@ static void sdma_wait_for_packet_egress(struct sdma_engine *sde,u64 off =8 * sde->this_idx;struct hfi1_devdata *dd = sde->dd;int lcnt =0 ; +u64 reg_prev; +u64 reg =0 ;while (1 ) { -u64 reg =read_csr (dd, off +SEND_EGRESS_SEND_DMA_STATUS ); + reg_prev = reg; + reg =read_csr (dd, off +SEND_EGRESS_SEND_DMA_STATUS ); reg &=SDMA_EGRESS_PACKET_OCCUPANCY_SMASK ; reg >>=SDMA_EGRESS_PACKET_OCCUPANCY_SHIFT ;if (reg ==0 )break ; -if (lcnt++ >100 ) { -dd_dev_err (dd,"%s: engine %u timeout waiting for packets to egress, remaining count %u\n" , +/* counter is reest if accupancy count changes */ +if (reg != reg_prev) + lcnt =0 ; +if (lcnt++ >500 ) { +/* timed out - bounce the link */ +dd_dev_err (dd,"%s: engine %u timeout waiting for packets to egress, remaining count %u, bouncing link\n" , __func__, sde->this_idx, (u32 )reg); +queue_work (dd->pport->hfi1_wq, + &dd->pport->link_bounce_work);break ; }udelay (1 );
Signature · 1 line
1.8.2
PATCH v3 5/23 staging/rdma/hfi1: Remove QSFP_ENABLED from HFI capability mask
In reply to [email protected]From: Easwar Hariharan <[email protected]>
The QSFP interface code has been running without issues and the flag is never set to off. This patch removes the QSFP_ENABLED bit from HFI1_CAP.
--- drivers/staging/rdma/hfi1/chip.c | 3 +-- drivers/staging/rdma/hfi1/common.h | 2 -- drivers/staging/rdma/hfi1/qsfp.c | 13 ++++--------- include/uapi/rdma/hfi/hfi1_user.h | 4 ++-- 4 files changed, 7 insertions(+), 15 deletions(-)
drivers/staging/rdma/hfi1/chip.c +1 -2
@@ -5716,8 +5716,7 @@ void init_qsfp(struct hfi1_pportdata *ppd)u64 qsfp_mask;if (loopback ==LOOPBACK_SERDES || loopback ==LOOPBACK_LCB || - ppd->dd->icode ==ICODE_FUNCTIONAL_SIMULATOR || - !HFI1_CAP_IS_KSET (QSFP_ENABLED )) { + ppd->dd->icode ==ICODE_FUNCTIONAL_SIMULATOR ) { ppd->driver_link_ready =1 ;return ; }
drivers/staging/rdma/hfi1/common.h +0 -2
@@ -147,7 +147,6 @@HFI1_CAP_USE_SDMA_HEAD | \HFI1_CAP_EXTENDED_PSN | \HFI1_CAP_PRINT_UNIMPL | \ -HFI1_CAP_QSFP_ENABLED | \HFI1_CAP_NO_INTEGRITY | \ HFI1_CAP_PKEY_CHECK) << \ HFI1_CAP_USER_SHIFT)
@@ -163,7 +162,6 @@HFI1_CAP_SDMA | \HFI1_CAP_PRINT_UNIMPL | \HFI1_CAP_STATIC_RATE_CTRL | \ -HFI1_CAP_QSFP_ENABLED | \HFI1_CAP_PKEY_CHECK | \HFI1_CAP_MULTI_PKT_EGR | \ HFI1_CAP_EXTENDED_PSN | \
drivers/staging/rdma/hfi1/qsfp.c +4 -9
@@ -403,16 +403,11 @@ static const char *pwr_codes = "1.5W2.0W2.5W3.5W";int qsfp_mod_present (struct hfi1_pportdata *ppd) { -if (HFI1_CAP_IS_KSET (QSFP_ENABLED )) { -struct hfi1_devdata *dd = ppd->dd; -u64 reg; +struct hfi1_devdata *dd = ppd->dd; +u64 reg; - reg =read_csr (dd, - dd->hfi1_id ?ASIC_QSFP2_IN :ASIC_QSFP1_IN ); -return !(reg &QSFP_HFI0_MODPRST_N ); - } -/* always return cable present */ -return 1 ; + reg =read_csr (dd, dd->hfi1_id ?ASIC_QSFP2_IN :ASIC_QSFP1_IN ); +return !(reg &QSFP_HFI0_MODPRST_N ); }/*
include/uapi/rdma/hfi/hfi1_user.h +2 -2
@@ -88,7 +88,7 @@#define HFI1_CAP_SDMA_AHG (1UL << 2)/* Enable SDMA AHG support */ #define HFI1_CAP_EXTENDED_PSN (1UL << 3)/* Enable Extended PSN support */ #define HFI1_CAP_HDRSUPP (1UL << 4)/* Enable Header Suppression */ -/* 1UL << 5 reserved */ +/* 1UL << 5 unused */ #define HFI1_CAP_USE_SDMA_HEAD (1UL << 6)/* DMA Hdr Q tail vs. use CSR */ #define HFI1_CAP_MULTI_PKT_EGR (1UL << 7)/* Enable multi-packet Egr buffs*/ #define HFI1_CAP_NODROP_RHQ_FULL (1UL << 8)/* Don't drop on Hdr Q full */
@@ -99,7 +99,7 @@#define HFI1_CAP_NO_INTEGRITY (1UL << 13)/* Enable ctxt integrity checks */ #define HFI1_CAP_PKEY_CHECK (1UL << 14)/* Enable ctxt PKey checking */ #define HFI1_CAP_STATIC_RATE_CTRL (1UL << 15)/* Allow PBC.StaticRateControl */ -#define HFI1_CAP_QSFP_ENABLED (1UL << 16)/* Enable QSFP check during LNI */ +/* 1UL << 16 unused */ #define HFI1_CAP_SDMA_HEAD_CHECK (1UL << 17)/* SDMA head checking */ #define HFI1_CAP_EARLY_CREDIT_RETURN (1UL << 18)/* early credit return */
Signature · 1 line
1.8.2
PATCH v3 6/23 staging/rdma/hfi1: Add coalescing support for SDMA TX descriptors
In reply to [email protected]From: Niranjana Vishwanathapura <[email protected]>
This fixes transmit errors when the number of scatter gather elements in the request is more that the number of per packet descriptors supported by the hardware, allocate and coalesce the extra scatter gather elements into a single buffer. The last descriptor is reserved and used for this coalesced buffer.
Verbs potentially need this support when transferring small data chunks involving different memory regions.
--- drivers/staging/rdma/hfi1/sdma.c | 124 ++++++++++++++++++++++++++++++++++++--- drivers/staging/rdma/hfi1/sdma.h | 74 +++++++++++++++-------- 2 files changed, 168 insertions(+), 30 deletions(-)
drivers/staging/rdma/hfi1/sdma.c +117 -7
@@ -55,6 +55,7 @@#include <linux/bitops.h> #include <linux/timer.h> #include <linux/vmalloc.h> +#include <linux/highmem.h> #include "hfi.h" #include "common.h"
@@ -2706,27 +2707,134 @@ static void __sdma_process_event(struct sdma_engine *sde,* of descriptors in the sdma_txreq is exhausted. * * The code will bump the allocation up to the max -* of MAX_DESC (64) descriptors. There doesn't seem -* much point in an interim step. +* of MAX_DESC (64) descriptors. There doesn't seem +* much point in an interim step. The last descriptor +* is reserved for coalesce buffer in order to support +* cases where input packet has >MAX_DESC iovecs. * */ -int _extend_sdma_tx_descs (struct hfi1_devdata *dd,struct sdma_txreq *tx) +static int _extend_sdma_tx_descs (struct hfi1_devdata *dd,struct sdma_txreq *tx) {int i; +/* Handle last descriptor */ +if (unlikely ((tx->num_desc == (MAX_DESC -1 )))) { +/* if tlen is 0, it is for padding, release last descriptor */ +if (!tx->tlen) { + tx->desc_limit =MAX_DESC ; + }else if (!tx->coalesce_buf) { +/* allocate coalesce buffer with space for padding */ + tx->coalesce_buf =kmalloc (tx->tlen +sizeof (u32), +GFP_ATOMIC ); +if (!tx->coalesce_buf) +return -ENOMEM ; + + tx->coalesce_idx =0 ; + } +return 0 ; + } + +if (unlikely (tx->num_desc ==MAX_DESC )) +return -ENOMEM ; + tx->descp =kmalloc_array (MAX_DESC ,sizeof (struct sdma_desc ),GFP_ATOMIC );if (!tx->descp)return -ENOMEM ; - tx->desc_limit =MAX_DESC ; + +/* reserve last descriptor for coalescing */ + tx->desc_limit =MAX_DESC -1 ;/* copy ones already built */ for (i =0 ; i < tx->num_desc; i++) tx->descp[i] = tx->descs[i];return 0 ; } +/* +* ext_coal_sdma_tx_descs() - extend or coalesce sdma tx descriptors +* +* This is called once the initial nominal allocation of descriptors +* in the sdma_txreq is exhausted. +* +* This function calls _extend_sdma_tx_descs to extend or allocate +* coalesce buffer. If there is a allocated coalesce buffer, it will +* copy the input packet data into the coalesce buffer. It also adds +* coalesce buffer descriptor once whe whole packet is received. +* +* Return: +* <0 - error +* 0 - coalescing, don't populate descriptor +* 1 - continue with populating descriptor +*/ +int ext_coal_sdma_tx_descs (struct hfi1_devdata *dd,struct sdma_txreq *tx, +int type,void *kvaddr,struct page *page, +unsigned long offset,u16 len) +{ +int pad_len, rval; +dma_addr_t addr; + + rval =_extend_sdma_tx_descs (dd, tx); +if (rval) { +sdma_txclean (dd, tx); +return rval; + } + +/* If coalesce buffer is allocated, copy data into it */ +if (tx->coalesce_buf) { +if (type ==SDMA_MAP_NONE ) { +sdma_txclean (dd, tx); +return -EINVAL ; + } + +if (type ==SDMA_MAP_PAGE ) { + kvaddr =kmap (page); + kvaddr += offset; + }else if (WARN_ON (!kvaddr)) { +sdma_txclean (dd, tx); +return -EINVAL ; + } + +memcpy (tx->coalesce_buf + tx->coalesce_idx, kvaddr, len); + tx->coalesce_idx += len; +if (type ==SDMA_MAP_PAGE ) +kunmap (page); + +/* If there is more data, return */ +if (tx->tlen - tx->coalesce_idx) +return 0 ; + +/* Whole packet is received; add any padding */ + pad_len = tx->packet_len & (sizeof (u32) -1 ); +if (pad_len) { + pad_len =sizeof (u32) - pad_len; +memset (tx->coalesce_buf + tx->coalesce_idx,0 , pad_len); +/* padding is taken care of for coalescing case */ + tx->packet_len += pad_len; + tx->tlen += pad_len; + } + +/* dma map the coalesce buffer */ + addr =dma_map_single (&dd->pcidev->dev, + tx->coalesce_buf, + tx->tlen, +DMA_TO_DEVICE ); + +if (unlikely (dma_mapping_error (&dd->pcidev->dev, addr))) { +sdma_txclean (dd, tx); +return -ENOSPC ; + } + +/* Add descriptor for coalesce buffer */ + tx->desc_limit =MAX_DESC ; +return _sdma_txadd_daddr (dd,SDMA_MAP_SINGLE , tx, + addr, tx->tlen); + } + +return 1 ; +} +/* Update sdes when the lmc changes */ void sdma_update_lmc (struct hfi1_devdata *dd,u64 mask,u32 lid) {
@@ -2752,13 +2860,15 @@ int _pad_sdma_tx_descs(struct hfi1_devdata *dd, struct sdma_txreq *tx) {int rval =0 ; + tx->num_desc++;if ((unlikely (tx->num_desc == tx->desc_limit))) { rval =_extend_sdma_tx_descs (dd, tx); -if (rval) +if (rval) { +sdma_txclean (dd, tx);return rval; + } } -/* finish the one just added */ - tx->num_desc++; +/* finish the one just added */ make_tx_sdma_desc( tx, SDMA_MAP_NONE,
drivers/staging/rdma/hfi1/sdma.h +51 -23
130 lines not on this page · raw message
Signature · 1 line
1.8.2
PATCH v3 8/23 staging/rdma/hfi1: Reset firmware instead of reloading Sbus
In reply to [email protected]From: Caz Yokoyama <[email protected]>
Reset firmware instead of reloading Sbus firmware if it's already done for this ASIC. To work around thermal polling problem in firmware, don't reload Sbus firmware, instead, reset the firmware on the initialization of the second HFI.
--- drivers/staging/rdma/hfi1/chip.h | 1 + drivers/staging/rdma/hfi1/firmware.c | 4 +--- drivers/staging/rdma/hfi1/pcie.c | 13 ++++++++++++- 3 files changed, 14 insertions(+), 4 deletions(-)
drivers/staging/rdma/hfi1/chip.h +1 -0
@@ -609,6 +609,7 @@ static inline void write_uctxt_csr(struct hfi1_devdata *dd, int ctxt,u64 create_pbc (struct hfi1_pportdata *ppd,u64 ,int ,u32 ,u32 );/* firmware.c */ +#define SBUS_MASTER_BROADCAST 0xfd#define NUM_PCIE_SERDES 16/* number of PCIe serdes on the SBus */ extern const u8 pcie_serdes_broadcast[];extern const u8 pcie_pcs_addrs[2 ][NUM_PCIE_SERDES ];
drivers/staging/rdma/hfi1/firmware.c +1 -3
@@ -924,9 +924,6 @@ static int load_8051_firmware(struct hfi1_devdata *dd,return 0 ; } -/* SBus Master broadcast address */ -#define SBUS_MASTER_BROADCAST 0xfd -/* * Write the SBus request register *
@@ -1255,6 +1252,7 @@ int load_firmware(struct hfi1_devdata *dd) ret =load_sbus_firmware (dd, &fw_sbus);if (ret) goto clear; + fw_sbus_load =0 ; }if (fw_fabric_serdes_load) {
drivers/staging/rdma/hfi1/pcie.c +12 -1
@@ -946,9 +946,20 @@ int do_pcie_gen3_transition(struct hfi1_devdata *dd) __func__); } +retry: +if (therm) { +/* toggle SPICO_ENABLE to get back to the state +just after the firmware load */ +sbus_request (dd,SBUS_MASTER_BROADCAST ,0x01 , +WRITE_SBUS_RECEIVER ,0x00000040 ); +sbus_request (dd,SBUS_MASTER_BROADCAST ,0x01 , +WRITE_SBUS_RECEIVER ,0x00000140 ); +dd_dev_info (dd,"%s: toggle SPICO_ENABLE to reset the bus\n" , + __func__); + } +/* step 3: download SBus Master firmware */ /* step 4: download PCIe Gen3 SerDes firmware */ -retry:dd_dev_info (dd,"%s: downloading firmware\n" , __func__); ret =load_pcie_firmware (dd);if (ret)
Signature · 1 line
1.8.2
PATCH v3 10/23 staging/rdma/hfi1: Fix port bounce issues with 0.22 DC firmware
In reply to [email protected]From: Easwar Hariharan <[email protected]>
The DC firmware overwrites the enable_lane_tx register and does not update it on a host request to go to Poll. This causes an infinite loop through the LNI state machine if a link width downgrade occurs. This patch re-sets the enable_lane_tx register to all 4 lanes.
--- drivers/staging/rdma/hfi1/chip.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/staging/rdma/hfi1/chip.c +2 -0
@@ -5417,6 +5417,8 @@ static int set_local_link_attributes(struct hfi1_pportdata *ppd)if (ppd->link_speed_enabled &OPA_LINK_SPEED_12_5G ) ppd->local_tx_rate |=1 ; } + + enable_lane_tx =0xF ;/* enable all four lanes */ ret =write_tx_settings (dd, enable_lane_tx, tx_polarity_inversion, rx_polarity_inversion, ppd->local_tx_rate);if (ret !=HCMD_SUCCESS )
Signature · 1 line
1.8.2
PATCH v3 11/23 staging/rdma/hfi1: Prevent silent data corruption with user SDMA
In reply to [email protected]From: Mitko Haralanov <[email protected]>
User SDMA keeps track of progress into the submitted IO vectors by tracking an offset into the vectors when packets are submitted. This offset is updated after a successful submission of a txreq to the SDMA engine.
The same offset was used when determining whether an IO vector should be 'freed' (pages unpinned) in the SDMA callback functions.
This was causing a silent data corruption in big jobs (> 2 nodes, 120 ranks each) on the receive side because the send side was mistakenly unpinning the vector pages before the HW has processed all descriptors referencing the vector.
--- drivers/staging/rdma/hfi1/user_sdma.c | 90 ++++++++++++++++++++--------------- 1 file changed, 52 insertions(+), 38 deletions(-)
drivers/staging/rdma/hfi1/user_sdma.c +52 -38
@@ -146,7 +146,8 @@ MODULE_PARM_DESC(sdma_comp_size, "Size of User SDMA completion ring. Default: 12#define KDETH_OM_MAX_SIZE (1 << ((KDETH_OM_LARGE / KDETH_OM_SMALL) + 1))/* Last packet in the request */ -#define USER_SDMA_TXREQ_FLAGS_LAST_PKT (1 << 0) +#define TXREQ_FLAGS_REQ_LAST_PKT (1 << 0) +#define TXREQ_FLAGS_IOVEC_LAST_PKT (1 << 0)#define SDMA_REQ_IN_USE 0#define SDMA_REQ_FOR_THREAD 1
@@ -249,13 +250,22 @@ struct user_sdma_request {unsigned long flags; }; +/* +* A single txreq could span up to 3 physical pages when the MTU +* is sufficiently large (> 4K). Each of the IOV pointers also +* needs it's own set of flags so the vector has been handled +* independently of each other. +*/ struct user_sdma_txreq {/* Packet header for the txreq */ struct hfi1_pkt_header hdr;struct sdma_txreq txreq;struct user_sdma_request *req; -struct user_sdma_iovec *iovec1; -struct user_sdma_iovec *iovec2; +struct { +struct user_sdma_iovec *vec; +u8 flags; + } iovecs[3 ]; +int idx;u16 flags;unsigned busycount;u64 seqnum;
@@ -294,21 +304,6 @@ static int defer_packet_queue( unsigned seq);static void activate_packet_queue (struct iowait *,int ); -static inline int iovec_may_free (struct user_sdma_iovec *iovec, -void (*free)(struct user_sdma_iovec *)) -{ -if (ACCESS_ONCE (iovec->offset) == iovec->iov.iov_len) { -free (iovec); -return 1 ; - } -return 0 ; -} - -static inline void iovec_set_complete (struct user_sdma_iovec *iovec) -{ - iovec->offset = iovec->iov.iov_len; -} - static int defer_packet_queue( struct sdma_engine *sde, struct iowait *wait,
@@ -825,11 +820,11 @@ static int user_sdma_send_pkts(struct user_sdma_request *req, unsigned maxpkts) tx->flags =0 ; tx->req = req; tx->busycount =0 ; - tx->iovec1 =NULL ; - tx->iovec2 =NULL ; + tx->idx =-1 ; +memset (tx->iovecs,0 ,sizeof (tx->iovecs));if (req->seqnum == req->info.npkts -1 ) - tx->flags |=USER_SDMA_TXREQ_FLAGS_LAST_PKT ; + tx->flags |=TXREQ_FLAGS_REQ_LAST_PKT ;/* * Calculate the payload size - this is min of the fragment
@@ -858,7 +853,7 @@ static int user_sdma_send_pkts(struct user_sdma_request *req, unsigned maxpkts) goto free_tx; } - tx->iovec1 = iovec; + tx->iovecs[++tx->idx].vec = iovec; datalen =compute_data_length (req, tx);if (!datalen) { SDMA_DBG(req,
@@ -948,10 +943,17 @@ static int user_sdma_send_pkts(struct user_sdma_request *req, unsigned maxpkts) iovec->pages[pageidx], offset, len);if (ret) { +int i; +dd_dev_err (pq->dd,"SDMA txreq add page failed %d\n" , ret); -iovec_set_complete (iovec); +/* Mark all assigned vectors as complete so they +* are unpinned in the callback. */ +for (i = tx->idx; i >=0 ; i--) { + tx->iovecs[i].flags |= +TXREQ_FLAGS_IOVEC_LAST_PKT ; + } goto free_txreq; } iov_offset += len;
@@ -959,8 +961,11 @@ static int user_sdma_send_pkts(struct user_sdma_request *req, unsigned maxpkts) data_sent += len;if (unlikely (queued < datalen && pageidx == iovec->npages && - req->iov_idx < req->data_iovs -1 )) { + req->iov_idx < req->data_iovs -1 && + tx->idx <ARRAY_SIZE (tx->iovecs))) { iovec->offset += iov_offset; + tx->iovecs[tx->idx].flags |= +TXREQ_FLAGS_IOVEC_LAST_PKT ; iovec = &req->iovs[++req->iov_idx];if (!iovec->pages) { ret =pin_vector_pages (req, iovec);
@@ -968,8 +973,7 @@ static int user_sdma_send_pkts(struct user_sdma_request *req, unsigned maxpkts) goto free_txreq; } iov_offset =0 ; - tx->iovec2 = iovec; - + tx->iovecs[++tx->idx].vec = iovec; } }/*
@@ -981,11 +985,15 @@ static int user_sdma_send_pkts(struct user_sdma_request *req, unsigned maxpkts) req->tidoffset += datalen; req->sent += data_sent;if (req->data_len) { -if (tx->iovec1 && !tx->iovec2) - tx->iovec1->offset += iov_offset; -else if (tx->iovec2) - tx->iovec2->offset += iov_offset; + tx->iovecs[tx->idx].vec->offset += iov_offset; +/* If we've reached the end of the io vector, mark it +* so the callback can unpin the pages and free it. */ +if (tx->iovecs[tx->idx].vec->offset == + tx->iovecs[tx->idx].vec->iov.iov_len) + tx->iovecs[tx->idx].flags |= +TXREQ_FLAGS_IOVEC_LAST_PKT ; } +/* * It is important to increment this here as it is used to * generate the BTH.PSN and, therefore, can't be bulk-updated
@@ -1214,7 +1222,7 @@ static int set_txreq_header(struct user_sdma_request *req, req->seqnum));/* Set ACK request on last packet */ -if (unlikely (tx->flags &USER_SDMA_TXREQ_FLAGS_LAST_PKT )) +if (unlikely (tx->flags &TXREQ_FLAGS_REQ_LAST_PKT )) hdr->bth[2 ] |=cpu_to_be32 (1UL <<31 );/* Set the new offset */
@@ -1246,7 +1254,7 @@ static int set_txreq_header(struct user_sdma_request *req,KDETH_SET (hdr->kdeth.ver_tid_offset,TID ,EXP_TID_GET (tidval,IDX ));/* Clear KDETH.SH only on the last packet */ -if (unlikely (tx->flags &USER_SDMA_TXREQ_FLAGS_LAST_PKT )) +if (unlikely (tx->flags &TXREQ_FLAGS_REQ_LAST_PKT ))KDETH_SET (hdr->kdeth.ver_tid_offset,SH ,0 );/* * Set the KDETH.OFFSET and KDETH.OM based on size of
@@ -1290,7 +1298,7 @@ static int set_txreq_header_ahg(struct user_sdma_request *req,/* BTH.PSN and BTH.A */ val32 = (be32_to_cpu (hdr->bth[2 ]) + req->seqnum) & (HFI1_CAP_IS_KSET (EXTENDED_PSN ) ?0x7fffffff :0xffffff ); -if (unlikely (tx->flags &USER_SDMA_TXREQ_FLAGS_LAST_PKT )) +if (unlikely (tx->flags &TXREQ_FLAGS_REQ_LAST_PKT )) val32 |=1UL <<31 ;AHG_HEADER_SET (req->ahg, diff,6 ,0 ,16 ,cpu_to_be16 (val32 >>16 ));AHG_HEADER_SET (req->ahg, diff,6 ,16 ,16 ,cpu_to_be16 (val32 &0xffff ));
@@ -1331,7 +1339,7 @@ static int set_txreq_header_ahg(struct user_sdma_request *req, val =cpu_to_le16 (((EXP_TID_GET (tidval,CTRL ) &0x3 ) <<10 ) | (EXP_TID_GET (tidval,IDX ) &0x3ff ));/* Clear KDETH.SH on last packet */ -if (unlikely (tx->flags &USER_SDMA_TXREQ_FLAGS_LAST_PKT )) { +if (unlikely (tx->flags &TXREQ_FLAGS_REQ_LAST_PKT )) { val |=cpu_to_le16 (KDETH_GET (hdr->kdeth.ver_tid_offset,INTR ) >>16 ); val &=cpu_to_le16 (~(1U <<13 ));
@@ -1358,10 +1366,16 @@ static void user_sdma_txreq_cb(struct sdma_txreq *txreq, int status,if (unlikely (!req || !pq))return ; -if (tx->iovec1) -iovec_may_free (tx->iovec1, unpin_vector_pages); -if (tx->iovec2) -iovec_may_free (tx->iovec2, unpin_vector_pages); +/* If we have any io vectors associated with this txreq, +* check whether they need to be 'freed'. */ +if (tx->idx !=-1 ) { +int i; + +for (i = tx->idx; i >=0 ; i--) { +if (tx->iovecs[i].flags &TXREQ_FLAGS_IOVEC_LAST_PKT ) +unpin_vector_pages (tx->iovecs[i].vec); + } + } tx_seqnum = tx->seqnum;kmem_cache_free (pq->txreq_cache, tx);
Signature · 1 line
1.8.2
PATCH v3 14/23 staging/rdma/hfi1: Implement Expected Receive TID caching
In reply to [email protected]From: Mitko Haralanov <[email protected]>
Expected receives work by user-space libraries (PSM) calling into the driver with information about the user's receive buffer and have the driver DMA-map that buffer and program the HFI to receive data directly into it.
This is an expensive operation as it requires the driver to pin the pages which
the user's buffer maps to, DMA-map them, and then program the HFI.
When the receive is complete, user-space libraries have to call into the driver again so the buffer is removed from the HFI, un-mapped, and the pages unpinned.
All of these operations are expensive, considering that a lot of applications (especially micro-benchmarks) use the same buffer over and over.
In order to get better performance for user-space applications, it is highly beneficial that they don't continuously call into the driver to register and unregister the same buffer. Rather, they can register the buffer and cache it for future work. The buffer can be unregistered when it is freed by the user.
This change implements such buffer caching by making use of the kernel's MMU notifier API. User-space libraries call into the driver only when the need to register a new buffer.
Once a buffer is registered, it stays programmed into the HFI until the kernel notifies the driver that the buffer has been freed by the user. At that time, the user-space library is notified and it can do the necessary work to remove the buffer from its cache.
Buffers which have been invalidated by the kernel are not automatically removed from the HFI and do not have their pages unpinned. Buffers are only completely removed when the user-space libraries call into the driver to free them. This is done to ensure that any ongoing transfers into that buffer are complete. This is important when a buffer is not completely freed but rather it is shrunk. The user-space library could still have uncompleted transfers into the remaining buffer.
With this feature, it is important that systems are setup with reasonable limits for the amount of lockable memory. Keeping the limit at "unlimited" (as we've done up to this point), may result in jobs being killed by the kernel's OOM due to them taking up excessive amounts of memory.
---
Changes from V2:
Fix random Kconfig 0-day build error
Fix leak of random memory to user space caught by Dan Carpenter Separate out pointer bug fix into a previous patch Change error checks in case statement per Dan's comments
drivers/staging/rdma/hfi1/Kconfig | 1 + drivers/staging/rdma/hfi1/Makefile | 2 +- drivers/staging/rdma/hfi1/common.h | 15 +- drivers/staging/rdma/hfi1/file_ops.c | 490 ++----------- drivers/staging/rdma/hfi1/hfi.h | 43 +- drivers/staging/rdma/hfi1/init.c | 5 +- drivers/staging/rdma/hfi1/trace.h | 132 ++-- drivers/staging/rdma/hfi1/user_exp_rcv.c | 1171 ++++++++++++++++++++++++++++++ drivers/staging/rdma/hfi1/user_exp_rcv.h | 82 +++ drivers/staging/rdma/hfi1/user_pages.c | 110 +-- drivers/staging/rdma/hfi1/user_sdma.c | 13 + drivers/staging/rdma/hfi1/user_sdma.h | 10 +- include/uapi/rdma/hfi/hfi1_user.h | 42 +- 13 files changed, 1481 insertions(+), 635 deletions(-) create mode 100644 drivers/staging/rdma/hfi1/user_exp_rcv.c create mode 100644 drivers/staging/rdma/hfi1/user_exp_rcv.h
drivers/staging/rdma/hfi1/Kconfig +1 -0
@@ -1,6 +1,7 @@ config INFINIBAND_HFI1 tristate "Intel OPA Gen1 support" depends on X86_64 + select MMU_NOTIFIER default m ---help--- This is a low-level driver for Intel OPA Gen1 adapter.
drivers/staging/rdma/hfi1/Makefile +1 -1
@@ -10,7 +10,7 @@ obj-$(CONFIG_INFINIBAND_HFI1) += hfi1.o hfi1-y := chip.o cq.o device.o diag.o dma.o driver.o eprom.o file_ops.o firmware.o \ init.o intr.o keys.o mad.o mmap.o mr.o pcie.o pio.o pio_copy.o \ qp.o qsfp.o rc.o ruc.o sdma.o srq.o sysfs.o trace.o twsi.o \ - uc.o ud.o user_pages.o user_sdma.o verbs_mcast.o verbs.o + uc.o ud.o user_exp_rcv.o user_pages.o user_sdma.o verbs_mcast.o verbs.o hfi1-$(CONFIG_DEBUG_FS) += debugfs.o CFLAGS_trace.o = -I$(src)
drivers/staging/rdma/hfi1/common.h +8 -7
@@ -132,13 +132,14 @@* HFI1_CAP_RESERVED_MASK bits. */ #define HFI1_CAP_WRITABLE_MASK (HFI1_CAP_SDMA_AHG | \ - HFI1_CAP_HDRSUPP | \ - HFI1_CAP_MULTI_PKT_EGR | \ - HFI1_CAP_NODROP_RHQ_FULL | \ - HFI1_CAP_NODROP_EGR_FULL | \ - HFI1_CAP_ALLOW_PERM_JKEY | \ - HFI1_CAP_STATIC_RATE_CTRL | \ - HFI1_CAP_PRINT_UNIMPL) + HFI1_CAP_HDRSUPP | \ + HFI1_CAP_MULTI_PKT_EGR | \ + HFI1_CAP_NODROP_RHQ_FULL | \ + HFI1_CAP_NODROP_EGR_FULL | \ + HFI1_CAP_ALLOW_PERM_JKEY | \ + HFI1_CAP_STATIC_RATE_CTRL | \ + HFI1_CAP_PRINT_UNIMPL | \ + HFI1_CAP_TID_UNMAP)/* * A set of capability bits that are "global" and are not allowed to be * set in the user bitmask.
drivers/staging/rdma/hfi1/file_ops.c +48 -442
616 lines not on this page · raw message
drivers/staging/rdma/hfi1/hfi.h +26 -17
86 lines not on this page · raw message
drivers/staging/rdma/hfi1/init.c +1 -4
@@ -219,7 +219,7 @@ struct hfi1_ctxtdata *hfi1_create_ctxtdata(struct hfi1_pportdata *ppd, u32 ctxt) rcd->numa_id =numa_node_id (); rcd->rcv_array_groups = dd->rcv_entries.ngroups; -spin_lock_init (&rcd->exp_lock); +mutex_init (&rcd->exp_lock);/* * Calculate the context's RcvArray entry starting point.
@@ -941,13 +941,10 @@ void hfi1_free_ctxtdata(struct hfi1_devdata *dd, struct hfi1_ctxtdata *rcd)kfree (rcd->egrbufs.buffers);sc_free (rcd->sc); -vfree (rcd->physshadow); -vfree (rcd->tid_pg_list);vfree (rcd->user_event_mask);vfree (rcd->subctxt_uregbase);vfree (rcd->subctxt_rcvegrbuf);vfree (rcd->subctxt_rcvhdr_base); -kfree (rcd->tidusemap);kfree (rcd->opstats);kfree (rcd); }
drivers/staging/rdma/hfi1/trace.h +85 -47
177 lines not on this page · raw message
drivers/staging/rdma/hfi1/user_exp_rcv.c new file +1171 -0
1,171 lines not on this page · raw message
drivers/staging/rdma/hfi1/user_exp_rcv.h new file +82 -0
82 lines not on this page · raw message
drivers/staging/rdma/hfi1/user_pages.c +24 -86
134 lines not on this page · raw message
drivers/staging/rdma/hfi1/user_sdma.c +13 -0
@@ -1055,6 +1055,12 @@ static int pin_vector_pages(struct user_sdma_request *req,/* If called by the kernel thread, use the user's mm */ if (current->flags &PF_KTHREAD )use_mm (req->user_proc->mm); +/* +* We should be calling hfi1_acquire_user_pages() so we can keep +* the number of pinned pages up-to-date. However, we can't do +* that because we can't use hfi1_release_user_pages() (see +* comment in unpin_vector_pages()). +*/ pinned =get_user_pages_fast ( (unsigned long )iovec->iov.iov_base, iovec->npages,0 , iovec->pages);
@@ -1084,6 +1090,13 @@ static void unpin_vector_pages(struct user_sdma_iovec *iovec) iovec->offset, iovec->iov.iov_len);return ; } +/* +* We should be calling hfi1_release_user_pages() so we can keep +* the number of pinned pages up-to-date. However, this function +* can be called in IRQ context and this will cause a deadlock +* because hfi1_release_user_pages() takes the mm semaphore, +* (which sleeps). +*/ for (i =0 ; i < iovec->npages; i++)if (iovec->pages[i])put_page (iovec->pages[i]);
drivers/staging/rdma/hfi1/user_sdma.h +1 -9
@@ -52,15 +52,7 @@#include "common.h" #include "iowait.h" - -#define EXP_TID_TIDLEN_MASK 0x7FFULL -#define EXP_TID_TIDLEN_SHIFT 0 -#define EXP_TID_TIDCTRL_MASK 0x3ULL -#define EXP_TID_TIDCTRL_SHIFT 20 -#define EXP_TID_TIDIDX_MASK 0x7FFULL -#define EXP_TID_TIDIDX_SHIFT 22 -#define EXP_TID_GET (tid, field) \ - (((tid) >> EXP_TID_TID##field##_SHIFT) & EXP_TID_TID##field##_MASK) +#include "user_exp_rcv.h" extern uint extended_psn;
include/uapi/rdma/hfi/hfi1_user.h +20 -22
76 lines not on this page · raw message
Signature · 1 line
1.8.2
Greg KH
maintainerRe: [PATCH v3 14/23] staging/rdma/hfi1: Implement Expected Receive TID caching
Quoted 55 lines · On Mon, Oct 26, 2015 at 10:28:40AM -0400, [email protected] wrote:
From: Mitko Haralanov <[email protected]>
Expected receives work by user-space libraries (PSM) calling into the driver with information about the user's receive buffer and have the driver DMA-map that buffer and program the HFI to receive data directly into it.
This is an expensive operation as it requires the driver to pin the pages which
the user's buffer maps to, DMA-map them, and then program the HFI.When the receive is complete, user-space libraries have to call into the driver again so the buffer is removed from the HFI, un-mapped, and the pages unpinned.
All of these operations are expensive, considering that a lot of applications (especially micro-benchmarks) use the same buffer over and over.
In order to get better performance for user-space applications, it is highly beneficial that they don't continuously call into the driver to register and unregister the same buffer. Rather, they can register the buffer and cache it for future work. The buffer can be unregistered when it is freed by the user.
This change implements such buffer caching by making use of the kernel's MMU notifier API. User-space libraries call into the driver only when the need to register a new buffer.
Once a buffer is registered, it stays programmed into the HFI until the kernel notifies the driver that the buffer has been freed by the user. At that time, the user-space library is notified and it can do the necessary work to remove the buffer from its cache.
Buffers which have been invalidated by the kernel are not automatically removed from the HFI and do not have their pages unpinned. Buffers are only completely removed when the user-space libraries call into the driver to free them. This is done to ensure that any ongoing transfers into that buffer are complete. This is important when a buffer is not completely freed but rather it is shrunk. The user-space library could still have uncompleted transfers into the remaining buffer.
With this feature, it is important that systems are setup with reasonable limits for the amount of lockable memory. Keeping the limit at "unlimited" (as we've done up to this point), may result in jobs being killed by the kernel's OOM due to them taking up excessive amounts of memory.
Reviewed-by Arthur Kepner <[email protected]>Reviewed-by Dennis Dalessandro <[email protected]>Signed-off-by Mitko Haralanov <[email protected]>Signed-off-by Ira Weiny <[email protected]>---
Changes from V2:
Fix randomKconfig0-day build error
Fix leak of random memory to user space caught by Dan Carpenter Separate out pointer bug fix into a previous patch Change error checks in case statement per Dan's comments
Quoted 16 lines
drivers/staging/rdma/hfi1/Kconfig | 1 + drivers/staging/rdma/hfi1/Makefile | 2 +- drivers/staging/rdma/hfi1/common.h | 15 +- drivers/staging/rdma/hfi1/file_ops.c | 490 ++----------- drivers/staging/rdma/hfi1/hfi.h | 43 +- drivers/staging/rdma/hfi1/init.c | 5 +- drivers/staging/rdma/hfi1/trace.h | 132 ++-- drivers/staging/rdma/hfi1/user_exp_rcv.c | 1171 ++++++++++++++++++++++++++++++ drivers/staging/rdma/hfi1/user_exp_rcv.h | 82 +++ drivers/staging/rdma/hfi1/user_pages.c | 110 +-- drivers/staging/rdma/hfi1/user_sdma.c | 13 + drivers/staging/rdma/hfi1/user_sdma.h | 10 +- include/uapi/rdma/hfi/hfi1_user.h | 42 +- 13 files changed, 1481 insertions(+), 635 deletions(-) create mode 100644 drivers/staging/rdma/hfi1/user_exp_rcv.c create mode 100644 drivers/staging/rdma/hfi1/user_exp_rcv.h
This is way too big to review properly, please break it up into reviewable chunks.
thanks,
greg k-h
PATCH v3 16/23 staging/rdma/hfi1: Increase SDMA descriptor queue size
In reply to [email protected]From: Ignacio Hernandez <[email protected]>
A value of 2048 increased PSM performance while not impacting verbs performance.
--- drivers/staging/rdma/hfi1/sdma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/staging/rdma/hfi1/sdma.c +1 -1
@@ -65,7 +65,7 @@#include "trace.h" /* must be a power of 2 >= 64 <= 32768 */ -#define SDMA_DESCQ_CNT 1024 +#define SDMA_DESCQ_CNT 2048#define SDMA_DESC_INTR 64#define INVALID_TAIL 0xffff
Signature · 1 line
1.8.2
PATCH v3 17/23 staging/rdma/hfi1: Add irqsaves in the packet processing path
In reply to [email protected]From: Dean Luick <[email protected]>
In preparation for threading the receive interrupt, add irqsaves in the packet processing path.
When the receive interrupt is threaded, the packet processing path is no longer guaranteed to have IRQs disabled. Add irqsaves where needed on several locks in the packet processing path. Anything that did not have an obvious, "close" irqsave in its caller is a candidate.
--- drivers/staging/rdma/hfi1/driver.c | 5 +++-- drivers/staging/rdma/hfi1/init.c | 5 +++-- drivers/staging/rdma/hfi1/mad.c | 4 ++-- drivers/staging/rdma/hfi1/rc.c | 19 +++++++++++-------- drivers/staging/rdma/hfi1/sdma.c | 9 +++++---- drivers/staging/rdma/hfi1/verbs.c | 9 +++++---- 6 files changed, 29 insertions(+), 22 deletions(-)
drivers/staging/rdma/hfi1/driver.c +3 -2
@@ -302,6 +302,7 @@ static void rcv_hdrerr(struct hfi1_ctxtdata *rcd, struct hfi1_pportdata *ppd, qp_num =be32_to_cpu (ohdr->bth[1 ]) &HFI1_QPN_MASK ;if (lid <HFI1_MULTICAST_LID_BASE ) {struct hfi1_qp *qp; +unsigned long flags;rcu_read_lock (); qp =hfi1_lookup_qpn (ibp, qp_num);
@@ -314,7 +315,7 @@ static void rcv_hdrerr(struct hfi1_ctxtdata *rcd, struct hfi1_pportdata *ppd,* Handle only RC QPs - for other QP types drop error * packet. */ -spin_lock (&qp->r_lock); +spin_lock_irqsave (&qp->r_lock, flags);/* Check for valid receive state. */ if (!(ib_hfi1_state_ops[qp->state] &
@@ -335,7 +336,7 @@ static void rcv_hdrerr(struct hfi1_ctxtdata *rcd, struct hfi1_pportdata *ppd,break ; } -spin_unlock (&qp->r_lock); +spin_unlock_irqrestore (&qp->r_lock, flags);rcu_read_unlock (); }/* Unicast QP */ }/* Valid packet with TIDErr */
drivers/staging/rdma/hfi1/init.c +3 -2
@@ -413,6 +413,7 @@ static enum hrtimer_restart cca_timer_fn(struct hrtimer *t)int sl;u16 ccti, ccti_timer, ccti_min;struct cc_state *cc_state; +unsigned long flags; cca_timer = container_of(t, struct cca_timer, hrtimer); ppd = cca_timer->ppd;
@@ -436,7 +437,7 @@ static enum hrtimer_restart cca_timer_fn(struct hrtimer *t) ccti_min = cc_state->cong_setting.entries[sl].ccti_min; ccti_timer = cc_state->cong_setting.entries[sl].ccti_timer; -spin_lock (&ppd->cca_timer_lock); +spin_lock_irqsave (&ppd->cca_timer_lock, flags); ccti = cca_timer->ccti;
@@ -445,7 +446,7 @@ static enum hrtimer_restart cca_timer_fn(struct hrtimer *t)set_link_ipg (ppd); } -spin_unlock (&ppd->cca_timer_lock); +spin_unlock_irqrestore (&ppd->cca_timer_lock, flags);rcu_read_unlock ();
drivers/staging/rdma/hfi1/mad.c +2 -2
@@ -3257,7 +3257,7 @@ static int __subn_get_opa_hfi1_cong_log(struct opa_smp *smp, u32 am,return reply ((struct ib_mad_hdr *)smp); } -spin_lock (&ppd->cc_log_lock); +spin_lock_irq (&ppd->cc_log_lock); cong_log->log_type =OPA_CC_LOG_TYPE_HFI ; cong_log->congestion_flags =0 ;
@@ -3300,7 +3300,7 @@ static int __subn_get_opa_hfi1_cong_log(struct opa_smp *smp, u32 am, sizeof(ppd->threshold_cong_event_map)); ppd->threshold_event_counter =0 ; -spin_unlock (&ppd->cc_log_lock); +spin_unlock_irq (&ppd->cc_log_lock);if (resp_len) *resp_len +=sizeof (struct opa_hfi1_cong_log );
drivers/staging/rdma/hfi1/rc.c +11 -8
@@ -697,6 +697,7 @@ void hfi1_send_rc_ack(struct hfi1_ctxtdata *rcd, struct hfi1_qp *qp,struct pio_buf *pbuf;struct hfi1_ib_header hdr;struct hfi1_other_headers *ohdr; +unsigned long flags;/* Don't send ACK or NAK if a RDMA read or atomic is pending. */ if (qp->s_flags &HFI1_S_RESP_PENDING )
@@ -771,7 +772,7 @@ void hfi1_send_rc_ack(struct hfi1_ctxtdata *rcd, struct hfi1_qp *qp, queue_ack:this_cpu_inc (*ibp->rc_qacks); -spin_lock (&qp->s_lock); +spin_lock_irqsave (&qp->s_lock, flags); qp->s_flags |=HFI1_S_ACK_PENDING |HFI1_S_RESP_PENDING ; qp->s_nak_state = qp->r_nak_state; qp->s_ack_psn = qp->r_ack_psn;
@@ -780,7 +781,7 @@ queue_ack:/* Schedule the send tasklet. */ hfi1_schedule_send (qp); -spin_unlock (&qp->s_lock); +spin_unlock_irqrestore (&qp->s_lock, flags); }/**
@@ -1152,7 +1153,7 @@ static struct hfi1_swqe *do_rc_completion(struct hfi1_qp *qp,* * This is called from rc_rcv_resp() to process an incoming RC ACK * for the given QP. -* Called at interrupt level with the QP s_lock held. +* May be called at interrupt level, with the QP s_lock held. * Returns 1 if OK, 0 if current operation should be aborted (NAK). */ static int do_rc_ack(struct hfi1_qp *qp, u32 aeth, u32 psn, int opcode,
@@ -1835,11 +1836,12 @@ static void log_cca_event(struct hfi1_pportdata *ppd, u8 sl, u32 rlid, u32 lqpn, u32 rqpn, u8 svc_type) { struct opa_hfi1_cong_log_event_internal *cc_event; +unsigned long flags;if (sl >=OPA_MAX_SLS )return ; -spin_lock (&ppd->cc_log_lock); +spin_lock_irqsave (&ppd->cc_log_lock, flags); ppd->threshold_cong_event_map[sl/8 ] |=1 << (sl %8 ); ppd->threshold_event_counter++;
@@ -1855,7 +1857,7 @@ static void log_cca_event(struct hfi1_pportdata *ppd, u8 sl, u32 rlid,/* keep timestamp in units of 1.024 usec */ cc_event->timestamp =ktime_to_ns (ktime_get ()) /1024 ; -spin_unlock (&ppd->cc_log_lock); +spin_unlock_irqrestore (&ppd->cc_log_lock, flags); } void process_becn(struct hfi1_pportdata *ppd, u8 sl, u16 rlid, u32 lqpn,
@@ -1865,6 +1867,7 @@ void process_becn(struct hfi1_pportdata *ppd, u8 sl, u16 rlid, u32 lqpn,u16 ccti, ccti_incr, ccti_timer, ccti_limit;u8 trigger_threshold;struct cc_state *cc_state; +unsigned long flags;if (sl >=OPA_MAX_SLS )return ;
@@ -1887,7 +1890,7 @@ void process_becn(struct hfi1_pportdata *ppd, u8 sl, u16 rlid, u32 lqpn, trigger_threshold = cc_state->cong_setting.entries[sl].trigger_threshold; -spin_lock (&ppd->cca_timer_lock); +spin_lock_irqsave (&ppd->cca_timer_lock, flags);if (cca_timer->ccti < ccti_limit) {if (cca_timer->ccti + ccti_incr <= ccti_limit)
@@ -1897,7 +1900,7 @@ void process_becn(struct hfi1_pportdata *ppd, u8 sl, u16 rlid, u32 lqpn,set_link_ipg (ppd); } -spin_unlock (&ppd->cca_timer_lock); +spin_unlock_irqrestore (&ppd->cca_timer_lock, flags); ccti = cca_timer->ccti;
@@ -1924,7 +1927,7 @@ void process_becn(struct hfi1_pportdata *ppd, u8 sl, u16 rlid, u32 lqpn,* * This is called from qp_rcv() to process an incoming RC packet * for the given QP. -* Called at interrupt level. +* May be called at interrupt level. */ void hfi1_rc_rcv (struct hfi1_packet *packet) {
drivers/staging/rdma/hfi1/sdma.c +5 -4
@@ -384,16 +384,17 @@ static void sdma_flush(struct sdma_engine *sde) {struct sdma_txreq *txp, *txp_next;LIST_HEAD (flushlist); +unsigned long flags;/* flush from head to tail */ sdma_flush_descq (sde); -spin_lock (&sde->flushlist_lock); +spin_lock_irqsave (&sde->flushlist_lock, flags);/* copy flush list */ list_for_each_entry_safe (txp, txp_next, &sde->flushlist, list) {list_del_init (&txp->list);list_add_tail (&txp->list, &flushlist); } -spin_unlock (&sde->flushlist_lock); +spin_unlock_irqrestore (&sde->flushlist_lock, flags);/* flush from flush list */ list_for_each_entry_safe (txp, txp_next, &flushlist, list) {int drained =0 ;
@@ -2097,9 +2098,9 @@ unlock_noconn: tx->sn = sde->tail_sn++;trace_hfi1_sdma_in_sn (sde, tx->sn);#endif -spin_lock (&sde->flushlist_lock); +spin_lock_irqsave (&sde->flushlist_lock, flags);list_add_tail (&tx->list, &sde->flushlist); -spin_unlock (&sde->flushlist_lock); +spin_unlock_irqrestore (&sde->flushlist_lock, flags);if (wait) { wait->tx_count++; wait->count += tx->num_desc;
drivers/staging/rdma/hfi1/verbs.c +5 -4
@@ -597,6 +597,7 @@ void hfi1_ib_rcv(struct hfi1_packet *packet)u32 tlen = packet->tlen;struct hfi1_pportdata *ppd = rcd->ppd;struct hfi1_ibport *ibp = &ppd->ibport_data; +unsigned long flags;u32 qp_num;int lnh;u8 opcode;
@@ -639,10 +640,10 @@ void hfi1_ib_rcv(struct hfi1_packet *packet) goto drop;list_for_each_entry_rcu (p, &mcast->qp_list, list) { packet->qp = p->qp; -spin_lock (&packet->qp->r_lock); +spin_lock_irqsave (&packet->qp->r_lock, flags);if (likely ((qp_ok (opcode, packet)))) opcode_handler_tbl[opcode](packet); -spin_unlock (&packet->qp->r_lock); +spin_unlock_irqrestore (&packet->qp->r_lock, flags); }/* * Notify hfi1_multicast_detach() if it is waiting for us
@@ -657,10 +658,10 @@ void hfi1_ib_rcv(struct hfi1_packet *packet)rcu_read_unlock (); goto drop; } -spin_lock (&packet->qp->r_lock); +spin_lock_irqsave (&packet->qp->r_lock, flags);if (likely ((qp_ok (opcode, packet)))) opcode_handler_tbl[opcode](packet); -spin_unlock (&packet->qp->r_lock); +spin_unlock_irqrestore (&packet->qp->r_lock, flags);rcu_read_unlock (); }return ;
Signature · 1 line
1.8.2