staging/rdma/hfi1: Fix bugs and performance issues
Subsystems (2)
v4 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.
New series based off of the latest staging-next. Large patches were split up and a new patch was added to remove offending macros.
NOTE: My apologies for not putting v4 in all the patches. I was not sure how to handle the fact that some of these had been previously submitted.
Ira Weiny (1):
staging/rdma/hfi1: Remove file pointer macros
Mike Marciniszyn (3):
staging/rdma/hfi1: move hfi1_migrate_qp staging/rdma/hfi1: Use parallel workqueue for SDMA engines staging/rdma/hfi: pre-compute sc and sde for RC/UC QPs
Mitko Haralanov (5):
staging/rdma/hfi1: Clean up macro indentation staging/rdma/hfi1: Remove unnecessary include files staging/rdma/hfi1: Move macros to a common header staging/rdma/hfi1: Add function stubs for TID caching staging/rdma/hfi1: Implement Expected Receive TID caching
drivers/staging/rdma/hfi1/Kconfig | 1 + drivers/staging/rdma/hfi1/Makefile | 2 +- drivers/staging/rdma/hfi1/chip.c | 1 + drivers/staging/rdma/hfi1/common.h | 15 +- drivers/staging/rdma/hfi1/file_ops.c | 598 +++------------ drivers/staging/rdma/hfi1/hfi.h | 55 +- drivers/staging/rdma/hfi1/init.c | 18 +- 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/trace.h | 132 ++-- drivers/staging/rdma/hfi1/ud.c | 1 + drivers/staging/rdma/hfi1/user_exp_rcv.c | 1174 ++++++++++++++++++++++++++++++ drivers/staging/rdma/hfi1/user_exp_rcv.h | 82 +++ drivers/staging/rdma/hfi1/user_pages.c | 110 +-- drivers/staging/rdma/hfi1/user_sdma.c | 47 +- drivers/staging/rdma/hfi1/user_sdma.h | 10 +- drivers/staging/rdma/hfi1/verbs.c | 34 +- drivers/staging/rdma/hfi1/verbs.h | 6 +- include/uapi/rdma/hfi/hfi1_user.h | 42 +- 23 files changed, 1670 insertions(+), 795 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): 1446245928-12675-1-git-send-email-ira.weiny-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org
PATCH v4 1/9 staging/rdma/hfi1: Remove file pointer macros
From: Ira Weiny <[email protected]>
Remove the following macros in favor of explicit use of struct hfi1_filedata and various sub structures.
ctxt_fpsubctxt_fptidcursor_fpuser_sdma_pkt_fpuser_sdma_comp_fp
--- drivers/staging/rdma/hfi1/file_ops.c | 124 ++++++++++++++++++---------------- drivers/staging/rdma/hfi1/hfi.h | 12 ---- drivers/staging/rdma/hfi1/user_sdma.c | 34 ++++++---- 3 files changed, 84 insertions(+), 86 deletions(-)
drivers/staging/rdma/hfi1/file_ops.c +65 -59
@@ -204,7 +204,8 @@ static ssize_t hfi1_file_write(struct file *fp, const char __user *data, size_t count, loff_t *offset) {const struct hfi1_cmd __user *ucmd; -struct hfi1_ctxtdata *uctxt =ctxt_fp (fp); +struct hfi1_filedata *fd = fp->private_data; +struct hfi1_ctxtdata *uctxt = fd->uctxt;struct hfi1_cmd cmd;struct hfi1_user_info uinfo;struct hfi1_tid_info tinfo;
@@ -338,17 +339,17 @@ static ssize_t hfi1_file_write(struct file *fp, const char __user *data, ret =exp_tid_free (fp, &tinfo);break ;case HFI1_CMD_RECV_CTRL : - ret =manage_rcvq (uctxt,subctxt_fp (fp), (int )user_val); + ret =manage_rcvq (uctxt, fd->subctxt, (int )user_val);break ;case HFI1_CMD_POLL_TYPE : uctxt->poll_type = (typeof(uctxt->poll_type))user_val;break ;case HFI1_CMD_ACK_EVENT : - ret =user_event_ack (uctxt,subctxt_fp (fp), user_val); + ret =user_event_ack (uctxt, fd->subctxt, user_val);break ;case HFI1_CMD_SET_PKEY :if (HFI1_CAP_IS_USET (PKEY_CHECK )) - ret =set_ctxt_pkey (uctxt,subctxt_fp (fp), user_val); + ret =set_ctxt_pkey (uctxt, fd->subctxt, user_val);else ret = -EPERM ;break ;
@@ -431,13 +432,13 @@ bail:static ssize_t hfi1_write_iter (struct kiocb *kiocb,struct iov_iter *from) { -struct hfi1_user_sdma_pkt_q *pq; -struct hfi1_user_sdma_comp_q *cq; +struct hfi1_filedata *fd = kiocb->ki_filp->private_data; +struct hfi1_user_sdma_pkt_q *pq = fd->pq; +struct hfi1_user_sdma_comp_q *cq = fd->cq;int ret =0 , done =0 , reqs =0 ;unsigned long dim = from->nr_segs; -if (!user_sdma_comp_fp (kiocb->ki_filp) || - !user_sdma_pkt_fp (kiocb->ki_filp)) { +if (!cq || !pq) { ret = -EIO ; goto done; }
@@ -448,10 +449,7 @@ static ssize_t hfi1_write_iter(struct kiocb *kiocb, struct iov_iter *from) }hfi1_cdbg (SDMA ,"SDMA request from %u:%u (%lu)" , -ctxt_fp (kiocb->ki_filp)->ctxt,subctxt_fp (kiocb->ki_filp), - dim); - pq =user_sdma_pkt_fp (kiocb->ki_filp); - cq =user_sdma_comp_fp (kiocb->ki_filp); + fd->uctxt->ctxt, fd->subctxt, dim);if (atomic_read (&pq->n_reqs) == pq->n_max_reqs) { ret = -ENOSPC ;
@@ -476,7 +474,8 @@ done:static int hfi1_file_mmap (struct file *fp,struct vm_area_struct *vma) { -struct hfi1_ctxtdata *uctxt; +struct hfi1_filedata *fd = fp->private_data; +struct hfi1_ctxtdata *uctxt = fd->uctxt;struct hfi1_devdata *dd;unsigned long flags, pfn; u64 token = vma->vm_pgoff << PAGE_SHIFT,
@@ -486,7 +485,6 @@ static int hfi1_file_mmap(struct file *fp, struct vm_area_struct *vma)int ret =0 ;u16 ctxt; - uctxt =ctxt_fp (fp);if (!is_valid_mmap (token) || !uctxt || !(vma->vm_flags &VM_SHARED )) { ret = -EINVAL ;
@@ -496,7 +494,7 @@ static int hfi1_file_mmap(struct file *fp, struct vm_area_struct *vma) ctxt =HFI1_MMAP_TOKEN_GET (CTXT , token); subctxt =HFI1_MMAP_TOKEN_GET (SUBCTXT , token); type =HFI1_MMAP_TOKEN_GET (TYPE , token); -if (ctxt != uctxt->ctxt || subctxt !=subctxt_fp (fp)) { +if (ctxt != uctxt->ctxt || subctxt != fd->subctxt) { ret = -EINVAL ; goto done; }
@@ -660,13 +658,12 @@ static int hfi1_file_mmap(struct file *fp, struct vm_area_struct *vma) vmf =1 ;break ;case SDMA_COMP : { -struct hfi1_user_sdma_comp_q *cq; +struct hfi1_user_sdma_comp_q *cq = fd->cq; -if (!user_sdma_comp_fp (fp)) { +if (!cq) { ret = -EFAULT ; goto done; } - cq =user_sdma_comp_fp (fp); memaddr = (u64 )cq->comps; memlen =ALIGN (sizeof (*cq->comps) * cq->nentries,PAGE_SIZE ); flags |=VM_IO |VM_DONTEXPAND ;
@@ -680,7 +677,7 @@ static int hfi1_file_mmap(struct file *fp, struct vm_area_struct *vma)if ((vma->vm_end - vma->vm_start) != memlen) {hfi1_cdbg (PROC ,"%u:%u Memory size mismatch %lu:%lu" , - uctxt->ctxt,subctxt_fp (fp), + uctxt->ctxt, fd->subctxt, (vma->vm_end - vma->vm_start), memlen); ret = -EINVAL ; goto done;
@@ -730,7 +727,7 @@ static unsigned int hfi1_poll(struct file *fp, struct poll_table_struct *pt)struct hfi1_ctxtdata *uctxt;unsigned pollflag; - uctxt =ctxt_fp (fp); + uctxt = ((struct hfi1_filedata *)fp->private_data)->uctxt;if (!uctxt) pollflag =POLLERR ;else if (uctxt->poll_type ==HFI1_POLL_TYPE_URGENT )
@@ -930,6 +927,7 @@ static int find_shared_ctxt(struct file *fp, {int devmax, ndev, i;int ret =0 ; +struct hfi1_filedata *fd = fp->private_data; devmax =hfi1_count_units (NULL ,NULL );
@@ -959,10 +957,10 @@ static int find_shared_ctxt(struct file *fp, ret = -EINVAL ; goto done; } -ctxt_fp (fp) = uctxt; -subctxt_fp (fp) = uctxt->cnt++; - uctxt->subpid[subctxt_fp (fp)] = current->pid; - uctxt->active_slaves |=1 <<subctxt_fp (fp); + fd->uctxt = uctxt; + fd->subctxt = uctxt->cnt++; + uctxt->subpid[fd->subctxt] = current->pid; + uctxt->active_slaves |=1 << fd->subctxt; ret =1 ; goto done; }
@@ -975,6 +973,7 @@ done:static int allocate_ctxt (struct file *fp,struct hfi1_devdata *dd,struct hfi1_user_info *uinfo) { +struct hfi1_filedata *fd = fp->private_data;struct hfi1_ctxtdata *uctxt;unsigned ctxt;int ret;
@@ -1022,7 +1021,7 @@ static int allocate_ctxt(struct file *fp, struct hfi1_devdata *dd,* This has to be done here so the rest of the sub-contexts find the * proper master. */ -if (uinfo->subctxt_cnt && !subctxt_fp (fp)) { +if (uinfo->subctxt_cnt && !fd->subctxt) { ret =init_subctxts (uctxt, uinfo);/* * On error, we don't need to disable and de-allocate the
@@ -1042,7 +1041,7 @@ static int allocate_ctxt(struct file *fp, struct hfi1_devdata *dd,spin_lock_init (&uctxt->sdma_qlock); hfi1_stats.sps_ctxts++; dd->freectxts--; -ctxt_fp (fp) = uctxt; + fd->uctxt = uctxt;return 0 ; }
@@ -1106,7 +1105,8 @@ static int user_init(struct file *fp) {int ret;unsigned int rcvctrl_ops =0 ; -struct hfi1_ctxtdata *uctxt =ctxt_fp (fp); +struct hfi1_filedata *fd = fp->private_data; +struct hfi1_ctxtdata *uctxt = fd->uctxt;/* make sure that the context has already been setup */ if (!test_bit (HFI1_CTXT_SETUP_DONE , &uctxt->event_flags)) {
@@ -1118,7 +1118,7 @@ static int user_init(struct file *fp)* Subctxts don't need to initialize anything since master * has done it. */ -if (subctxt_fp (fp)) { +if (fd->subctxt) { ret =wait_event_interruptible (uctxt->wait, !test_bit (HFI1_CTXT_MASTER_UNINIT , &uctxt->event_flags));
@@ -1178,8 +1178,8 @@ done:static int get_ctxt_info (struct file *fp,void __user *ubase,__u32 len) {struct hfi1_ctxt_info cinfo; -struct hfi1_ctxtdata *uctxt =ctxt_fp (fp);struct hfi1_filedata *fd = fp->private_data; +struct hfi1_ctxtdata *uctxt = fd->uctxt;int ret =0 ;memset (&cinfo,0 ,sizeof (cinfo));
@@ -1189,7 +1189,7 @@ static int get_ctxt_info(struct file *fp, void __user *ubase, __u32 len) cinfo.num_active =hfi1_count_active_units (); cinfo.unit = uctxt->dd->unit; cinfo.ctxt = uctxt->ctxt; - cinfo.subctxt =subctxt_fp (fp); + cinfo.subctxt = fd->subctxt; cinfo.rcvtids =roundup (uctxt->egrbufs.alloced, uctxt->dd->rcv_entries.group_size) + uctxt->expected_count;
@@ -1201,10 +1201,10 @@ static int get_ctxt_info(struct file *fp, void __user *ubase, __u32 len) cinfo.egrtids = uctxt->egrbufs.alloced; cinfo.rcvhdrq_cnt = uctxt->rcvhdrq_cnt; cinfo.rcvhdrq_entsize = uctxt->rcvhdrqentsize <<2 ; - cinfo.sdma_ring_size =user_sdma_comp_fp (fp)->nentries; + cinfo.sdma_ring_size = fd->cq->nentries; cinfo.rcvegr_size = uctxt->egrbufs.rcvtid_size; -trace_hfi1_ctxt_info (uctxt->dd, uctxt->ctxt,subctxt_fp (fp), cinfo); +trace_hfi1_ctxt_info (uctxt->dd, uctxt->ctxt, fd->subctxt, cinfo);if (copy_to_user (ubase, &cinfo,sizeof (cinfo))) ret = -EFAULT ; done:
@@ -1213,7 +1213,8 @@ done:static int setup_ctxt (struct file *fp) { -struct hfi1_ctxtdata *uctxt =ctxt_fp (fp); +struct hfi1_filedata *fd = fp->private_data; +struct hfi1_ctxtdata *uctxt = fd->uctxt;struct hfi1_devdata *dd = uctxt->dd;int ret =0 ;
@@ -1222,7 +1223,7 @@ static int setup_ctxt(struct file *fp)* programming of eager buffers. This is done if context sharing * is not requested or by the master process. */ -if (!uctxt->subctxt_cnt || !subctxt_fp (fp)) { +if (!uctxt->subctxt_cnt || !fd->subctxt) { ret =hfi1_init_ctxt (uctxt->sc);if (ret) goto done;
@@ -1234,7 +1235,7 @@ static int setup_ctxt(struct file *fp) ret =hfi1_setup_eagerbufs (uctxt);if (ret) goto done; -if (uctxt->subctxt_cnt && !subctxt_fp (fp)) { +if (uctxt->subctxt_cnt && !fd->subctxt) { ret =setup_subctxt (uctxt);if (ret) goto done;
@@ -1277,7 +1278,7 @@ static int setup_ctxt(struct file *fp) uctxt->tidusemap[uctxt->tidmapcnt -1 ] = ~((1ULL << (uctxt->numtidgroups %BITS_PER_LONG )) -1 ); -trace_hfi1_exp_tid_map (uctxt->ctxt,subctxt_fp (fp),0 , +trace_hfi1_exp_tid_map (uctxt->ctxt, fd->subctxt,0 , uctxt->tidusemap, uctxt->tidmapcnt); } ret =hfi1_user_sdma_alloc_queues (uctxt, fp);
@@ -1292,7 +1293,8 @@ done:static int get_base_info (struct file *fp,void __user *ubase,__u32 len) {struct hfi1_base_info binfo; -struct hfi1_ctxtdata *uctxt =ctxt_fp (fp); +struct hfi1_filedata *fd = fp->private_data; +struct hfi1_ctxtdata *uctxt = fd->uctxt;struct hfi1_devdata *dd = uctxt->dd;ssize_t sz;unsigned offset;
@@ -1314,50 +1316,50 @@ static int get_base_info(struct file *fp, void __user *ubase, __u32 len) offset = ((u64 )uctxt->sc->hw_free - (u64 )dd->cr_base[uctxt->numa_id].va) %PAGE_SIZE ; binfo.sc_credits_addr =HFI1_MMAP_TOKEN (PIO_CRED , uctxt->ctxt, -subctxt_fp (fp), offset); + fd->subctxt, offset); binfo.pio_bufbase =HFI1_MMAP_TOKEN (PIO_BUFS , uctxt->ctxt, -subctxt_fp (fp), + fd->subctxt, uctxt->sc->base_addr); binfo.pio_bufbase_sop =HFI1_MMAP_TOKEN (PIO_BUFS_SOP , uctxt->ctxt, -subctxt_fp (fp), + fd->subctxt, uctxt->sc->base_addr); binfo.rcvhdr_bufbase =HFI1_MMAP_TOKEN (RCV_HDRQ , uctxt->ctxt, -subctxt_fp (fp), + fd->subctxt, uctxt->rcvhdrq); binfo.rcvegr_bufbase =HFI1_MMAP_TOKEN (RCV_EGRBUF , uctxt->ctxt, -subctxt_fp (fp), + fd->subctxt, uctxt->egrbufs.rcvtids[0 ].phys); binfo.sdma_comp_bufbase =HFI1_MMAP_TOKEN (SDMA_COMP , uctxt->ctxt, -subctxt_fp (fp),0 ); + fd->subctxt,0 );/* * user regs are at * (RXE_PER_CONTEXT_USER + (ctxt * RXE_PER_CONTEXT_SIZE)) */ binfo.user_regbase =HFI1_MMAP_TOKEN (UREGS , uctxt->ctxt, -subctxt_fp (fp),0 ); + fd->subctxt,0 ); offset =offset_in_page ((((uctxt->ctxt - dd->first_user_ctxt) * -HFI1_MAX_SHARED_CTXTS ) +subctxt_fp (fp)) * +HFI1_MAX_SHARED_CTXTS ) + fd->subctxt) *sizeof (*dd->events)); binfo.events_bufbase =HFI1_MMAP_TOKEN (EVENTS , uctxt->ctxt, -subctxt_fp (fp), + fd->subctxt, offset); binfo.status_bufbase =HFI1_MMAP_TOKEN (STATUS , uctxt->ctxt, -subctxt_fp (fp), + fd->subctxt, dd->status);if (HFI1_CAP_IS_USET (DMA_RTAIL )) binfo.rcvhdrtail_base =HFI1_MMAP_TOKEN (RTAIL , uctxt->ctxt, -subctxt_fp (fp),0 ); + fd->subctxt,0 );if (uctxt->subctxt_cnt) { binfo.subctxt_uregbase =HFI1_MMAP_TOKEN (SUBCTXT_UREGS , uctxt->ctxt, -subctxt_fp (fp),0 ); + fd->subctxt,0 ); binfo.subctxt_rcvhdrbuf =HFI1_MMAP_TOKEN (SUBCTXT_RCV_HDRQ , uctxt->ctxt, -subctxt_fp (fp),0 ); + fd->subctxt,0 ); binfo.subctxt_rcvegrbuf =HFI1_MMAP_TOKEN (SUBCTXT_EGRBUF , uctxt->ctxt, -subctxt_fp (fp),0 ); + fd->subctxt,0 ); } sz = (len <sizeof (binfo)) ? len :sizeof (binfo);if (copy_to_user (ubase, &binfo, sz))
@@ -1368,7 +1370,8 @@ static int get_base_info(struct file *fp, void __user *ubase, __u32 len)static unsigned int poll_urgent (struct file *fp,struct poll_table_struct *pt) { -struct hfi1_ctxtdata *uctxt =ctxt_fp (fp); +struct hfi1_filedata *fd = fp->private_data; +struct hfi1_ctxtdata *uctxt = fd->uctxt;struct hfi1_devdata *dd = uctxt->dd;unsigned pollflag;
@@ -1390,7 +1393,8 @@ static unsigned int poll_urgent(struct file *fp,static unsigned int poll_next (struct file *fp,struct poll_table_struct *pt) { -struct hfi1_ctxtdata *uctxt =ctxt_fp (fp); +struct hfi1_filedata *fd = fp->private_data; +struct hfi1_ctxtdata *uctxt = fd->uctxt;struct hfi1_devdata *dd = uctxt->dd;unsigned pollflag;
@@ -1562,7 +1566,8 @@ static inline unsigned num_free_groups(unsigned long map, u16 *start)static int exp_tid_setup (struct file *fp,struct hfi1_tid_info *tinfo) {int ret =0 ; -struct hfi1_ctxtdata *uctxt =ctxt_fp (fp); +struct hfi1_filedata *fd = fp->private_data; +struct hfi1_ctxtdata *uctxt = fd->uctxt;struct hfi1_devdata *dd = uctxt->dd;unsigned tid, mapped =0 , npages, ngroups, exp_groups, tidpairs = uctxt->expected_count /2 ;
@@ -1718,7 +1723,7 @@ static int exp_tid_setup(struct file *fp, struct hfi1_tid_info *tinfo) pages[pmapped],0 , tidsize, PCI_DMA_FROMDEVICE);trace_hfi1_exp_rcv_set (uctxt->ctxt, -subctxt_fp (fp), + fd->subctxt, tid, vaddr, phys[pmapped], pages[pmapped]);
@@ -1763,7 +1768,7 @@ static int exp_tid_setup(struct file *fp, struct hfi1_tid_info *tinfo) (((useidx &0xffffff ) <<16 ) | ((bitidx + bits_used) & 0xffffff))); } -trace_hfi1_exp_tid_map (uctxt->ctxt,subctxt_fp (fp),0 , uctxt->tidusemap, +trace_hfi1_exp_tid_map (uctxt->ctxt, fd->subctxt,0 , uctxt->tidusemap, uctxt->tidmapcnt); done:
@@ -1792,7 +1797,8 @@ bail:static int exp_tid_free (struct file *fp,struct hfi1_tid_info *tinfo) { -struct hfi1_ctxtdata *uctxt =ctxt_fp (fp); +struct hfi1_filedata *fd = fp->private_data; +struct hfi1_ctxtdata *uctxt = fd->uctxt;struct hfi1_devdata *dd = uctxt->dd;unsigned long tidmap[uctxt->tidmapcnt];struct page **pages;
@@ -1828,7 +1834,7 @@ static int exp_tid_free(struct file *fp, struct hfi1_tid_info *tinfo)hfi1_put_tid (dd, tid,PT_INVALID ,0 ,0 );trace_hfi1_exp_rcv_free (uctxt->ctxt, -subctxt_fp (fp), + fd->subctxt, tid, phys[i], pages[i]); pci_unmap_page(dd->pcidev, phys[i],
@@ -1845,7 +1851,7 @@ static int exp_tid_free(struct file *fp, struct hfi1_tid_info *tinfo) map &= ~(1ULL <<bitidx); } } -trace_hfi1_exp_tid_map (uctxt->ctxt,subctxt_fp (fp),1 , uctxt->tidusemap, +trace_hfi1_exp_tid_map (uctxt->ctxt, fd->subctxt,1 , uctxt->tidusemap, uctxt->tidmapcnt); done:return ret;
drivers/staging/rdma/hfi1/hfi.h +0 -12
@@ -1423,18 +1423,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;
drivers/staging/rdma/hfi1/user_sdma.c +19 -15
@@ -352,6 +352,7 @@ static void sdma_kmem_cache_ctor(void *obj)int hfi1_user_sdma_alloc_queues (struct hfi1_ctxtdata *uctxt,struct file *fp) { +struct hfi1_filedata *fd;int ret =0 ;unsigned memsize;char buf[64 ];
@@ -365,6 +366,8 @@ int hfi1_user_sdma_alloc_queues(struct hfi1_ctxtdata *uctxt, struct file *fp) goto done; } + fd = fp->private_data; +if (!hfi1_sdma_comp_ring_size) { ret = -EINVAL ; goto done;
@@ -384,7 +387,7 @@ int hfi1_user_sdma_alloc_queues(struct hfi1_ctxtdata *uctxt, struct file *fp)INIT_LIST_HEAD (&pq->list); pq->dd = dd; pq->ctxt = uctxt->ctxt; - pq->subctxt =subctxt_fp (fp); + pq->subctxt = fd->subctxt; pq->n_max_reqs = hfi1_sdma_comp_ring_size; pq->state =SDMA_PKT_Q_INACTIVE ;atomic_set (&pq->n_reqs,0 );
@@ -393,7 +396,7 @@ int hfi1_user_sdma_alloc_queues(struct hfi1_ctxtdata *uctxt, struct file *fp) activate_packet_queue); pq->reqidx =0 ;snprintf (buf,64 ,"txreq-kmem-cache-%u-%u-%u" , dd->unit, uctxt->ctxt, -subctxt_fp (fp)); + fd->subctxt); pq->txreq_cache = kmem_cache_create(buf, sizeof(struct user_sdma_txreq), L1_CACHE_BYTES,
@@ -404,7 +407,7 @@ int hfi1_user_sdma_alloc_queues(struct hfi1_ctxtdata *uctxt, struct file *fp) uctxt->ctxt); goto pq_txreq_nomem; } -user_sdma_pkt_fp (fp) = pq; + fd->pq = pq; cq =kzalloc (sizeof (*cq),GFP_KERNEL );if (!cq) goto cq_nomem;
@@ -416,7 +419,7 @@ int hfi1_user_sdma_alloc_queues(struct hfi1_ctxtdata *uctxt, struct file *fp) goto cq_comps_nomem; cq->nentries = hfi1_sdma_comp_ring_size; -user_sdma_comp_fp (fp) = cq; + fd->cq = cq;spin_lock_irqsave (&uctxt->sdma_qlock, flags);list_add (&pq->list, &uctxt->sdma_queues);
@@ -431,7 +434,7 @@ pq_txreq_nomem:kfree (pq->reqs); pq_reqs_nomem:kfree (pq); -user_sdma_pkt_fp (fp) =NULL ; + fd->pq =NULL ; pq_nomem: ret = -ENOMEM ; done:
@@ -485,9 +488,10 @@ int hfi1_user_sdma_process_request(struct file *fp, struct iovec *iovec, unsigned long dim, unsigned long *count) { int ret = 0, i = 0, sent; -struct hfi1_ctxtdata *uctxt =ctxt_fp (fp); -struct hfi1_user_sdma_pkt_q *pq =user_sdma_pkt_fp (fp); -struct hfi1_user_sdma_comp_q *cq =user_sdma_comp_fp (fp); +struct hfi1_filedata *fd = fp->private_data; +struct hfi1_ctxtdata *uctxt = fd->uctxt; +struct hfi1_user_sdma_pkt_q *pq = fd->pq; +struct hfi1_user_sdma_comp_q *cq = fd->cq;struct hfi1_devdata *dd = pq->dd;unsigned long idx =0 ;u8 pcount = initial_pkt_count;
@@ -499,7 +503,7 @@ int hfi1_user_sdma_process_request(struct file *fp, struct iovec *iovec,hfi1_cdbg (SDMA ,"[%u:%u:%u] First vector not big enough for header %lu/%lu" , - dd->unit, uctxt->ctxt,subctxt_fp (fp), + dd->unit, uctxt->ctxt, fd->subctxt, iovec[idx].iov_len,sizeof (info) +sizeof (req->hdr)); ret = -EINVAL ; goto done;
@@ -507,15 +511,15 @@ int hfi1_user_sdma_process_request(struct file *fp, struct iovec *iovec, ret =copy_from_user (&info, iovec[idx].iov_base,sizeof (info));if (ret) {hfi1_cdbg (SDMA ,"[%u:%u:%u] Failed to copy info QW (%d)" , - dd->unit, uctxt->ctxt,subctxt_fp (fp), ret); + dd->unit, uctxt->ctxt, fd->subctxt, ret); ret = -EFAULT ; goto done; } -trace_hfi1_sdma_user_reqinfo (dd, uctxt->ctxt,subctxt_fp (fp), +trace_hfi1_sdma_user_reqinfo (dd, uctxt->ctxt, fd->subctxt, (u16 *)&info);if (cq->comps[info.comp_idx].status ==QUEUED ) {hfi1_cdbg (SDMA ,"[%u:%u:%u] Entry %u is in QUEUED state" , - dd->unit, uctxt->ctxt,subctxt_fp (fp), + dd->unit, uctxt->ctxt, fd->subctxt, info.comp_idx); ret = -EBADSLT ; goto done;
@@ -523,7 +527,7 @@ int hfi1_user_sdma_process_request(struct file *fp, struct iovec *iovec,if (!info.fragsize) {hfi1_cdbg (SDMA ,"[%u:%u:%u:%u] Request does not specify fragsize" , - dd->unit, uctxt->ctxt,subctxt_fp (fp), info.comp_idx); + dd->unit, uctxt->ctxt, fd->subctxt, info.comp_idx); ret = -EINVAL ; goto done; }
@@ -532,7 +536,7 @@ int hfi1_user_sdma_process_request(struct file *fp, struct iovec *iovec,* "allocate" the request entry. */ hfi1_cdbg (SDMA ,"[%u:%u:%u] Using req/comp entry %u\n" , dd->unit, - uctxt->ctxt,subctxt_fp (fp), info.comp_idx); + uctxt->ctxt, fd->subctxt, info.comp_idx); req = pq->reqs + info.comp_idx;memset (req,0 ,sizeof (*req));/* Mark the request as IN_USE before we start filling it in. */
@@ -659,7 +663,7 @@ int hfi1_user_sdma_process_request(struct file *fp, struct iovec *iovec,/* Have to select the engine */ req->sde =sdma_select_engine_vl (dd, - (u32)(uctxt->ctxt +subctxt_fp (fp)), + (u32)(uctxt->ctxt + fd->subctxt), vl);if (!req->sde || !sdma_running (req->sde)) { ret = -ECOMM ;
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 v4 2/9 staging/rdma/hfi1: Clean up macro indentation
In reply to a message not in the archiveFrom: Mitko Haralanov <[email protected]>
In preparation for implementing Expected TID caching we do some simple clean up of header file macros.
--- drivers/staging/rdma/hfi1/common.h | 15 ++++++++------- include/uapi/rdma/hfi/hfi1_user.h | 26 +++++++++++++------------- 2 files changed, 21 insertions(+), 20 deletions(-)
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.
include/uapi/rdma/hfi/hfi1_user.h +13 -13
@@ -127,13 +127,13 @@#define HFI1_CMD_TID_UPDATE 4/* update expected TID entries */ #define HFI1_CMD_TID_FREE 5/* free expected TID entries */ #define HFI1_CMD_CREDIT_UPD 6/* force an update of PIO credit */ -#define HFI1_CMD_SDMA_STATUS_UPD 7/* force update of SDMA status ring */ +#define HFI1_CMD_SDMA_STATUS_UPD 7/* force update of SDMA status ring */ #define HFI1_CMD_RECV_CTRL 8/* control receipt of packets */ #define HFI1_CMD_POLL_TYPE 9/* set the kind of polling we want */ #define HFI1_CMD_ACK_EVENT 10/* ack & clear user status bits */ -#define HFI1_CMD_SET_PKEY 11/* set context's pkey */ -#define HFI1_CMD_CTXT_RESET 12/* reset context's HW send context */ +#define HFI1_CMD_SET_PKEY 11/* set context's pkey */ +#define HFI1_CMD_CTXT_RESET 12/* reset context's HW send context */ /* separate EPROM commands from normal PSM commands */ #define HFI1_CMD_EP_INFO 64/* read EPROM device ID */ #define HFI1_CMD_EP_ERASE_CHIP 65/* erase whole EPROM */
@@ -144,18 +144,18 @@#define HFI1_CMD_EP_WRITE_P0 70/* write EPROM partition 0 */ #define HFI1_CMD_EP_WRITE_P1 71/* write EPROM partition 1 */ -#define _HFI1_EVENT_FROZEN_BIT 0 -#define _HFI1_EVENT_LINKDOWN_BIT 1 -#define _HFI1_EVENT_LID_CHANGE_BIT 2 -#define _HFI1_EVENT_LMC_CHANGE_BIT 3 -#define _HFI1_EVENT_SL2VL_CHANGE_BIT 4 +#define _HFI1_EVENT_FROZEN_BIT 0 +#define _HFI1_EVENT_LINKDOWN_BIT 1 +#define _HFI1_EVENT_LID_CHANGE_BIT 2 +#define _HFI1_EVENT_LMC_CHANGE_BIT 3 +#define _HFI1_EVENT_SL2VL_CHANGE_BIT 4#define _HFI1_MAX_EVENT_BIT _HFI1_EVENT_SL2VL_CHANGE_BIT -#define HFI1_EVENT_FROZEN (1UL << _HFI1_EVENT_FROZEN_BIT) -#define HFI1_EVENT_LINKDOWN_BIT (1UL << _HFI1_EVENT_LINKDOWN_BIT) -#define HFI1_EVENT_LID_CHANGE_BIT (1UL << _HFI1_EVENT_LID_CHANGE_BIT) -#define HFI1_EVENT_LMC_CHANGE_BIT (1UL << _HFI1_EVENT_LMC_CHANGE_BIT) -#define HFI1_EVENT_SL2VL_CHANGE_BIT (1UL << _HFI1_EVENT_SL2VL_CHANGE_BIT) +#define HFI1_EVENT_FROZEN (1UL << _HFI1_EVENT_FROZEN_BIT) +#define HFI1_EVENT_LINKDOWN (1UL << _HFI1_EVENT_LINKDOWN_BIT) +#define HFI1_EVENT_LID_CHANGE (1UL << _HFI1_EVENT_LID_CHANGE_BIT) +#define HFI1_EVENT_LMC_CHANGE (1UL << _HFI1_EVENT_LMC_CHANGE_BIT) +#define HFI1_EVENT_SL2VL_CHANGE (1UL << _HFI1_EVENT_SL2VL_CHANGE_BIT)/* * These are the status bits readable (in ASCII form, 64bit value)
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 v4 3/9 staging/rdma/hfi1: Remove unnecessary include files
In reply to a message not in the archiveFrom: Mitko Haralanov <[email protected]>
These includes were not used in file_ops.c
--- drivers/staging/rdma/hfi1/file_ops.c | 10 ---------- 1 file changed, 10 deletions(-)
drivers/staging/rdma/hfi1/file_ops.c +0 -10
@@ -47,20 +47,10 @@* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ -#include <linux/pci.h> #include <linux/poll.h> #include <linux/cdev.h> -#include <linux/swap.h> #include <linux/vmalloc.h> -#include <linux/highmem.h> #include <linux/io.h> -#include <linux/jiffies.h> -#include <asm/pgtable.h> -#include <linux/delay.h> -#include <linux/export.h> -#include <linux/module.h> -#include <linux/cred.h> -#include <linux/uio.h> #include "hfi.h" #include "pio.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
PATCH v4 4/9 staging/rdma/hfi1: Move macros to a common header
In reply to a message not in the archiveFrom: Mitko Haralanov <[email protected]>
In preparation of implementing TID caching move EXP_TID macros to a common header user_exp_rcv.h
--- drivers/staging/rdma/hfi1/file_ops.c | 13 +----- drivers/staging/rdma/hfi1/user_exp_rcv.h | 74 ++++++++++++++++++++++++++++++++ drivers/staging/rdma/hfi1/user_sdma.h | 10 +---- 3 files changed, 76 insertions(+), 21 deletions(-) create mode 100644 drivers/staging/rdma/hfi1/user_exp_rcv.h
drivers/staging/rdma/hfi1/file_ops.c +1 -12
@@ -58,6 +58,7 @@#include "common.h" #include "trace.h" #include "user_sdma.h" +#include "user_exp_rcv.h" #include "eprom.h" #undef pr_fmt
@@ -160,18 +161,6 @@ enum mmap_types { HFI1_MMAP_TOKEN_SET(SUBCTXT, subctxt) | \ HFI1_MMAP_TOKEN_SET(OFFSET, (offset_in_page(addr)))) -#define EXP_TID_SET (field, value) \ - (((value) & EXP_TID_TID##field##_MASK) << \ - EXP_TID_TID##field##_SHIFT) -#define EXP_TID_CLEAR (tid, field) { \ - (tid) &= ~(EXP_TID_TID##field##_MASK << \ - EXP_TID_TID##field##_SHIFT); \ - } -#define EXP_TID_RESET (tid, field, value) do { \ - EXP_TID_CLEAR(tid, field); \ - (tid) |= EXP_TID_SET(field, value); \ - } while (0) -#define dbg (fmt, ...) \ pr_info(fmt, ##__VA_ARGS__)
drivers/staging/rdma/hfi1/user_exp_rcv.h new file +74 -0
74 lines not on this page · raw message
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;
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 v4 5/9 staging/rdma/hfi1: Add function stubs for TID caching
In reply to a message not in the archiveFrom: Mitko Haralanov <[email protected]>
Add mmu notify helper functions and TID caching function stubs in preparation for the TID caching implementation.
TID caching makes use of the MMU notifier to allow the driver to respond to the user freeing memory which is allocated to the HFI.
This patch implements the basic MMU notifier functions to insert, find and remove buffer pages from memory based on the mmu_notifier being invoked.
In addition it places stubs in place for the main entry points by follow on code.
Follow up patches will complete the implementation of the interaction with user space and makes use of these functions.
--- drivers/staging/rdma/hfi1/Kconfig | 1 + drivers/staging/rdma/hfi1/Makefile | 2 +- drivers/staging/rdma/hfi1/user_exp_rcv.c | 314 +++++++++++++++++++++++++++++++ drivers/staging/rdma/hfi1/user_exp_rcv.h | 8 + 4 files changed, 324 insertions(+), 1 deletion(-) create mode 100644 drivers/staging/rdma/hfi1/user_exp_rcv.c
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/user_exp_rcv.c new file +314 -0
314 lines not on this page · raw message
drivers/staging/rdma/hfi1/user_exp_rcv.h +8 -0
@@ -50,6 +50,8 @@* */ +#include "hfi.h" +#define EXP_TID_TIDLEN_MASK 0x7FFULL#define EXP_TID_TIDLEN_SHIFT 0#define EXP_TID_TIDCTRL_MASK 0x3ULL
@@ -71,4 +73,10 @@ (tid) |=EXP_TID_SET (field, (value)); \ } while (0) +int hfi1_user_exp_rcv_init(struct file *); +int hfi1_user_exp_rcv_free (struct hfi1_filedata *); +int hfi1_user_exp_rcv_setup (struct file *,struct hfi1_tid_info *); +int hfi1_user_exp_rcv_clear (struct file *,struct hfi1_tid_info *); +int hfi1_user_exp_rcv_invalid (struct file *,struct hfi1_tid_info *); +#endif /* _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
Greg KH
maintainerRe: [PATCH v4 5/9] staging/rdma/hfi1: Add function stubs for TID caching
Quoted 8 lines · On Fri, Oct 30, 2015 at 06:58:44PM -0400, [email protected] wrote:
From: Mitko Haralanov <[email protected]>
Add mmu notify helper functions and TID caching function stubs in preparation for the TID caching implementation.
TID caching makes use of the MMU notifier to allow the driver to respond to the user freeing memory which is allocated to the HFI.
Quoted 8 lines
This patch implements the basic MMU notifier functions to insert, find and remove buffer pages from memory based on the
mmu_notifierbeing invoked.In addition it places stubs in place for the main entry points by follow on code.
Follow up patches will complete the implementation of the interaction with user space and makes use of these functions.
This patch adds warnings to the build, which isn't ok, so I've stopped here in this series and just applied the first 4. Please fix up and resend the remaining ones.
thanks,
greg k-h
A message that is not in the archive (sent off-list or not yet received): [email protected]
Re: [PATCH v4 5/9] staging/rdma/hfi1: Add function stubs for TID caching
Quoted 15 lines · Greg KH
Quoted 14 lines · On Fri, Oct 30, 2015 at 06:58:44PM -0400…
From: Mitko Haralanov <[email protected]>
Add mmu notify helper functions and TID caching function stubs in preparation for the TID caching implementation.
TID caching makes use of the MMU notifier to allow the driver to respond to the user freeing memory which is allocated to the HFI.
This patch implements the basic MMU notifier functions to insert, find and remove buffer pages from memory based on the
mmu_notifierbeing invoked.In addition it places stubs in place for the main entry points by follow on code.
Quoted 6 lines
Quoted 2 lines
Follow up patches will complete the implementation of the interaction with user space and makes use of these functions.
This patch adds warnings to the build, which isn't ok, so I've stopped here in this series and just applied the first 4. Please fix up and resend the remaining ones.
Ok, patch 7-9 of this series do not depend on this patch nor number 6. I will resend those 3 while I figure out what to do about these 2:
staging/rdma/hfi1: Add function stubs for TID caching staging/rdma/hfi1: Implement Expected Receive TID caching
Frankly this was an attempt to reduce the size of "Implement Expected Receive TID caching". I obviously did something wrong.
I really don't know that I can split these up any more without causing issues with bisecting the code.
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): 20151110001102.GA11150-W4f6Xiosr+yv7QzWx2u06xL4W9x8LtSr@public.gmane.org
Re: [PATCH v4 5/9] staging/rdma/hfi1: Add function stubs for TID caching
Quoted 26 lines · ira.weiny
Quoted 15 lines · Greg KH
Quoted 14 lines · On Fri, Oct 30, 2015 at 06:58:44PM -0400…
From: Mitko Haralanov <[email protected]>
Add mmu notify helper functions and TID caching function stubs in preparation for the TID caching implementation.
TID caching makes use of the MMU notifier to allow the driver to respond to the user freeing memory which is allocated to the HFI.
This patch implements the basic MMU notifier functions to insert, find and remove buffer pages from memory based on the
mmu_notifierbeing invoked.In addition it places stubs in place for the main entry points by follow on code.
Quoted 6 lines
Quoted 2 lines
Follow up patches will complete the implementation of the interaction with user space and makes use of these functions.
This patch adds warnings to the build, which isn't ok, so I've stopped here in this series and just applied the first 4. Please fix up and resend the remaining ones.
Ok, patch 7-9 of this series do not depend on this patch nor number 6. I will resend those 3 while I figure out what to do about these 2:
Quoted 8 lines
staging/rdma/hfi1: Add function stubs for TID caching staging/rdma/hfi1: Implement Expected Receive TID caching
Frankly this was an attempt to reduce the size of "Implement Expected Receive TID caching". I obviously did something wrong.
I really don't know that I can split these up any more without causing issues with bisecting the code.
I strongly doubt that you created this new feature all "at once", it took a set of steps to get to your final destination. So show that work, like your math professor told you...
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 v4 5/9] staging/rdma/hfi1: Add function stubs for TID caching
Quoted 10 lines
Quoted 10 lines
Ok, patch 7-9 of this series do not depend on this patch nor number 6. I will resend those 3 while I figure out what to do about these 2:
staging/rdma/hfi1: Add function stubs for TID caching staging/rdma/hfi1: Implement Expected Receive TID caching
Frankly this was an attempt to reduce the size of "Implement Expected Receive TID caching". I obviously did something wrong.
Quoted 7 lines
Quoted 2 lines
I really don't know that I can split these up any more without causing issues with bisecting the code.
I strongly doubt that you created this new feature all "at once", it took a set of steps to get to your final destination. So show that work, like your math professor told you...
The original author and I have been going through the code to see what we can do. We have identified a couple of other pieces which can be split.
One question. Is it ok to have functionality which is added which is unused in a preliminary patch? I believe this is ok as long as the code compiles but I just wanted to make sure. While there are different operations added in this patch it is broken to not use them as a set. So we need to have a series which implement the pieces with a final patch which exposes the set of operations.
Is this acceptable?
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): 20151111061039.GB9594-W4f6Xiosr+yv7QzWx2u06xL4W9x8LtSr@public.gmane.org
Re: [PATCH v4 5/9] staging/rdma/hfi1: Add function stubs for TID caching
Quoted 10 lines · ira.weiny
The original author and I have been going through the code to see what we can do. We have identified a couple of other pieces which can be split.
One question. Is it ok to have functionality which is added which is unused in a preliminary patch? I believe this is ok as long as the code compiles but I just wanted to make sure. While there are different operations added in this patch it is broken to not use them as a set. So we need to have a series which implement the pieces with a final patch which exposes the set of operations.
Is this acceptable?
Yeah. It's fine. Don't add warnings about unused static functions though. Also we like to see a user in the same patchset so don't add infrastructure first and the user code the next year or whatever.
regards,
dan carpenter
--
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 v4 6/9 staging/rdma/hfi1: Implement Expected Receive TID caching
In reply to a message not in the archiveFrom: 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 V3:
Reworked based on the removal of the file pointer macros Split out some prep patches and code clean up
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/file_ops.c | 469 ++--------------- 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 | 874 ++++++++++++++++++++++++++++++- drivers/staging/rdma/hfi1/user_pages.c | 110 +--- drivers/staging/rdma/hfi1/user_sdma.c | 13 + include/uapi/rdma/hfi/hfi1_user.h | 14 +- 8 files changed, 1069 insertions(+), 591 deletions(-)
drivers/staging/rdma/hfi1/file_ops.c +47 -422
@@ -96,9 +96,6 @@ static int user_event_ack(struct hfi1_ctxtdata *, int, unsigned long);static int set_ctxt_pkey (struct hfi1_ctxtdata *,unsigned ,u16 );static int manage_rcvq (struct hfi1_ctxtdata *,unsigned ,int );static int vma_fault (struct vm_area_struct *,struct vm_fault *); -static int exp_tid_setup (struct file *,struct hfi1_tid_info *); -static int exp_tid_free (struct file *,struct hfi1_tid_info *); -static void unlock_exp_tids (struct hfi1_ctxtdata *);static const struct file_operations hfi1_file_ops = { .owner =THIS_MODULE ,
@@ -174,8 +171,12 @@ static int hfi1_file_open(struct inode *inode, struct file *fp) {/* The real work is performed later in assign_ctxt() */ fp->private_data =kzalloc (sizeof (struct hfi1_filedata ),GFP_KERNEL ); -if (fp->private_data)/* no cpu affinity by default */ - ((struct hfi1_filedata *)fp->private_data)->rec_cpu_num =-1 ; +if (fp->private_data) { +struct hfi1_filedata *fd = fp->private_data; + +/* no cpu affinity by default */ + fd->rec_cpu_num =-1 ; + }return fp->private_data ?0 : -ENOMEM ; }
@@ -188,6 +189,7 @@ static ssize_t hfi1_file_write(struct file *fp, const char __user *data,struct hfi1_cmd cmd;struct hfi1_user_info uinfo;struct hfi1_tid_info tinfo; +unsigned long addr;ssize_t consumed =0 , copy =0 , ret =0 ;void *dest =NULL ;__u64 user_val =0 ;
@@ -219,6 +221,7 @@ static ssize_t hfi1_file_write(struct file *fp, const char __user *data,break ;case HFI1_CMD_TID_UPDATE :case HFI1_CMD_TID_FREE : +case HFI1_CMD_TID_INVAL_READ : copy =sizeof (tinfo); dest = &tinfo;break ;
@@ -297,9 +300,8 @@ static ssize_t hfi1_file_write(struct file *fp, const char __user *data,sc_return_credits (uctxt->sc);break ;case HFI1_CMD_TID_UPDATE : - ret =exp_tid_setup (fp, &tinfo); + ret =hfi1_user_exp_rcv_setup (fp, &tinfo);if (!ret) { -unsigned long addr;/* * Copy the number of tidlist entries we used * and the length of the buffer we registered.
@@ -314,8 +316,25 @@ static ssize_t hfi1_file_write(struct file *fp, const char __user *data, ret = -EFAULT ; }break ; +case HFI1_CMD_TID_INVAL_READ : + ret =hfi1_user_exp_rcv_invalid (fp, &tinfo); +if (ret) +break ; + addr = (unsigned long )cmd.addr + + offsetof(struct hfi1_tid_info , tidcnt); +if (copy_to_user ((void __user *)addr, &tinfo.tidcnt, +sizeof (tinfo.tidcnt))) + ret = -EFAULT ; +break ;case HFI1_CMD_TID_FREE : - ret =exp_tid_free (fp, &tinfo); + ret =hfi1_user_exp_rcv_clear (fp, &tinfo); +if (ret) +break ; + addr = (unsigned long )cmd.addr + + offsetof(struct hfi1_tid_info , tidcnt); +if (copy_to_user ((void __user *)addr, &tinfo.tidcnt, +sizeof (tinfo.tidcnt))) + ret = -EFAULT ;break ;case HFI1_CMD_RECV_CTRL : ret =manage_rcvq (uctxt, fd->subctxt, (int )user_val);
@@ -736,6 +755,7 @@ static int hfi1_file_close(struct inode *inode, struct file *fp)mutex_lock (&hfi1_mutex);flush_wc (); +/* drain user sdma queue */ if (fdata->pq)hfi1_user_sdma_free_queues (fdata);
@@ -785,12 +805,9 @@ static int hfi1_file_close(struct inode *inode, struct file *fp) uctxt->pionowait =0 ; uctxt->event_flags =0 ; -hfi1_clear_tids (uctxt); +hfi1_user_exp_rcv_free (fdata);hfi1_clear_ctxt_pkey (dd, uctxt->ctxt); -if (uctxt->tid_pg_list) -unlock_exp_tids (uctxt); - hfi1_stats.sps_ctxts--; dd->freectxts++;mutex_unlock (&hfi1_mutex);
@@ -994,6 +1011,7 @@ static int allocate_ctxt(struct file *fp, struct hfi1_devdata *dd, ret =sc_enable (uctxt->sc);if (ret)return ret; +/* * Setup shared context resources if the user-level has requested * shared contexts and this is the 'master' process.
@@ -1028,22 +1046,19 @@ static int allocate_ctxt(struct file *fp, struct hfi1_devdata *dd,static int init_subctxts (struct hfi1_ctxtdata *uctxt,const struct hfi1_user_info *uinfo) { -int ret =0 ;unsigned num_subctxts; num_subctxts = uinfo->subctxt_cnt; -if (num_subctxts >HFI1_MAX_SHARED_CTXTS ) { - ret = -EINVAL ; - goto bail; - } +if (num_subctxts >HFI1_MAX_SHARED_CTXTS ) +return -EINVAL ; uctxt->subctxt_cnt = uinfo->subctxt_cnt; uctxt->subctxt_id = uinfo->subctxt_id; uctxt->active_slaves =1 ; uctxt->redirect_seq_cnt =1 ;set_bit (HFI1_CTXT_MASTER_UNINIT , &uctxt->event_flags); -bail: -return ret; + +return 0 ; }static int setup_subctxt (struct hfi1_ctxtdata *uctxt)
@@ -1101,7 +1116,7 @@ static int user_init(struct file *fp) ret =wait_event_interruptible (uctxt->wait, !test_bit (HFI1_CTXT_MASTER_UNINIT , &uctxt->event_flags)); - goto done; + goto expected; }/* initialize poll variables... */
@@ -1148,8 +1163,18 @@ static int user_init(struct file *fp)clear_bit (HFI1_CTXT_MASTER_UNINIT , &uctxt->event_flags);wake_up (&uctxt->wait); } - ret =0 ; +expected: +/* +* Expected receive has to be setup for all processes (including +* shared contexts). However, it has to be done after the master +* context has been fully configured as it depends on the +* eager/expected split of the RcvArray entries. +* Setting it up here ensures that the subcontexts will be waiting +* (due to the above wait_event_interruptible() until the master +* is setup. +*/ + ret =hfi1_user_exp_rcv_init (fp); done:return ret; }
@@ -1203,6 +1228,7 @@ static int setup_ctxt(struct file *fp)* is not requested or by the master process. */ if (!uctxt->subctxt_cnt || !fd->subctxt) { + ret =hfi1_init_ctxt (uctxt->sc);if (ret) goto done;
@@ -1219,46 +1245,6 @@ static int setup_ctxt(struct file *fp)if (ret) goto done; } -/* Setup Expected Rcv memories */ - uctxt->tid_pg_list =vzalloc (uctxt->expected_count * -sizeof (struct page **)); -if (!uctxt->tid_pg_list) { - ret = -ENOMEM ; - goto done; - } - uctxt->physshadow =vzalloc (uctxt->expected_count * -sizeof (*uctxt->physshadow)); -if (!uctxt->physshadow) { - ret = -ENOMEM ; - goto done; - } -/* allocate expected TID map and initialize the cursor */ -atomic_set (&uctxt->tidcursor,0 ); - uctxt->numtidgroups = uctxt->expected_count / - dd->rcv_entries.group_size; - uctxt->tidmapcnt = uctxt->numtidgroups /BITS_PER_LONG + - !!(uctxt->numtidgroups %BITS_PER_LONG ); - uctxt->tidusemap =kzalloc_node (uctxt->tidmapcnt * -sizeof (*uctxt->tidusemap), -GFP_KERNEL , uctxt->numa_id); -if (!uctxt->tidusemap) { - ret = -ENOMEM ; - goto done; - } -/* -* In case that the number of groups is not a multiple of -* 64 (the number of groups in a tidusemap element), mark -* the extra ones as used. This will effectively make them -* permanently used and should never be assigned. Otherwise, -* the code which checks how many free groups we have will -* get completely confused about the state of the bits. -*/ -if (uctxt->numtidgroups %BITS_PER_LONG ) - uctxt->tidusemap[uctxt->tidmapcnt -1 ] = - ~((1ULL << (uctxt->numtidgroups % -BITS_PER_LONG )) -1 ); -trace_hfi1_exp_tid_map (uctxt->ctxt, fd->subctxt,0 , - uctxt->tidusemap, uctxt->tidmapcnt); } ret =hfi1_user_sdma_alloc_queues (uctxt, fp);if (ret)
@@ -1497,367 +1483,6 @@ static int user_event_ack(struct hfi1_ctxtdata *uctxt, int subctxt,return 0 ; } -#define num_user_pages (vaddr, len) \ - (1 + (((((unsigned long)(vaddr) + \ - (unsigned long)(len) - 1) & PAGE_MASK) - \ - ((unsigned long)vaddr & PAGE_MASK)) >> PAGE_SHIFT)) - -/** -* tzcnt - count the number of trailing zeros in a 64bit value -* @value: the value to be examined -* -* Returns the number of trailing least significant zeros in the -* the input value. If the value is zero, return the number of -* bits of the value. -*/ -static inline u8 tzcnt (u64 value) -{ -return value ?__builtin_ctzl (value) :sizeof (value) *8 ; -} - -static inline unsigned num_free_groups (unsigned long map,u16 *start) -{ -unsigned free; -u16 bitidx = *start; - -if (bitidx >=BITS_PER_LONG ) -return 0 ; -/* "Turn off" any bits set before our bit index */ - map &= ~((1ULL << bitidx) -1 ); - free =tzcnt (map) - bitidx; -while (!free && bitidx <BITS_PER_LONG ) { -/* Zero out the last set bit so we look at the rest */ - map &= ~(1ULL << bitidx); -/* -* Account for the previously checked bits and advance -* the bit index. We don't have to check for bitidx -* getting bigger than BITS_PER_LONG here as it would -* mean extra instructions that we don't need. If it -* did happen, it would push free to a negative value -* which will break the loop. -*/ - free =tzcnt (map) - ++bitidx; - } - *start = bitidx; -return free; -} - -static int exp_tid_setup (struct file *fp,struct hfi1_tid_info *tinfo) -{ -int ret =0 ; -struct hfi1_filedata *fd = fp->private_data; -struct hfi1_ctxtdata *uctxt = fd->uctxt; -struct hfi1_devdata *dd = uctxt->dd; -unsigned tid, mapped =0 , npages, ngroups, exp_groups, - tidpairs = uctxt->expected_count /2 ; -struct page **pages; -unsigned long vaddr, tidmap[uctxt->tidmapcnt]; -dma_addr_t *phys; -u32 tidlist[tidpairs], pairidx =0 , tidcursor; -u16 useidx, idx, bitidx, tidcnt =0 ; - - vaddr = tinfo->vaddr; - -if (offset_in_page (vaddr)) { - ret = -EINVAL ; - goto bail; - } - - npages =num_user_pages (vaddr, tinfo->length); -if (!npages) { - ret = -EINVAL ; - goto bail; - } -if (!access_ok (VERIFY_WRITE , (void __user *)vaddr, - npages *PAGE_SIZE )) { -dd_dev_err (dd,"Fail vaddr %p, %u pages, !access_ok\n" , - (void *)vaddr, npages); - ret = -EFAULT ; - goto bail; - } - -memset (tidmap,0 ,sizeof (tidmap[0 ]) * uctxt->tidmapcnt); -memset (tidlist,0 ,sizeof (tidlist[0 ]) * tidpairs); - - exp_groups = uctxt->expected_count / dd->rcv_entries.group_size; -/* which group set do we look at first? */ - tidcursor =atomic_read (&uctxt->tidcursor); - useidx = (tidcursor >>16 ) &0xffff ; - bitidx = tidcursor &0xffff ; - -/* -* Keep going until we've mapped all pages or we've exhausted all -* RcvArray entries. -* This iterates over the number of tidmaps + 1 -* (idx <= uctxt->tidmapcnt) so we check the bitmap which we -* started from one more time for any free bits before the -* starting point bit. -*/ -for (mapped =0 , idx =0 ; - mapped < npages && idx <= uctxt->tidmapcnt;) { -u64 i, offset =0 ; -unsigned free, pinned, pmapped =0 , bits_used; -u16 grp; - -/* -* "Reserve" the needed group bits under lock so other -* processes can't step in the middle of it. Once -* reserved, we don't need the lock anymore since we -* are guaranteed the groups. -*/ -spin_lock (&uctxt->exp_lock); -if (uctxt->tidusemap[useidx] ==-1ULL || - bitidx >=BITS_PER_LONG ) { -/* no free groups in the set, use the next */ - useidx = (useidx +1 ) % uctxt->tidmapcnt; - idx++; - bitidx =0 ; -spin_unlock (&uctxt->exp_lock); -continue ; - } - ngroups = ((npages - mapped) / dd->rcv_entries.group_size) + - !!((npages - mapped) % dd->rcv_entries.group_size); - -/* -* If we've gotten here, the current set of groups does have -* one or more free groups. -*/ - free =num_free_groups (uctxt->tidusemap[useidx], &bitidx); -if (!free) { -/* -* Despite the check above, free could still come back -* as 0 because we don't check the entire bitmap but -* we start from bitidx. -*/ -spin_unlock (&uctxt->exp_lock); -continue ; - } - bits_used =min (free, ngroups); - tidmap[useidx] |= ((1ULL << bits_used) -1 ) << bitidx; - uctxt->tidusemap[useidx] |= tidmap[useidx]; -spin_unlock (&uctxt->exp_lock); - -/* -* At this point, we know where in the map we have free bits. -* properly offset into the various "shadow" arrays and compute -* the RcvArray entry index. -*/ - offset = ((useidx *BITS_PER_LONG ) + bitidx) * - dd->rcv_entries.group_size; - pages = uctxt->tid_pg_list + offset; - phys = uctxt->physshadow + offset; - tid = uctxt->expected_base + offset; - -/* Calculate how many pages we can pin based on free bits */ - pinned =min ((bits_used * dd->rcv_entries.group_size), - (npages - mapped)); -/* -* Now that we know how many free RcvArray entries we have, -* we can pin that many user pages. -*/ - ret =hfi1_get_user_pages (vaddr + (mapped *PAGE_SIZE ), - pinned, pages); -if (ret) { -/* -* We can't continue because the pages array won't be -* initialized. This should never happen, -* unless perhaps the user has mpin'ed the pages -* themselves. -*/ -dd_dev_info (dd, -"Failed to lock addr %p, %u pages: errno %d\n" , - (void *) vaddr, pinned, -ret); -/* -* Let go of the bits that we reserved since we are not -* going to use them. -*/ -spin_lock (&uctxt->exp_lock); - uctxt->tidusemap[useidx] &= - ~(((1ULL << bits_used) -1 ) << bitidx); -spin_unlock (&uctxt->exp_lock); - goto done; - } -/* -* How many groups do we need based on how many pages we have -* pinned? -*/ - ngroups = (pinned / dd->rcv_entries.group_size) + - !!(pinned % dd->rcv_entries.group_size); -/* -* Keep programming RcvArray entries for all the <ngroups> free -* groups. -*/ -for (i =0 , grp =0 ; grp < ngroups; i++, grp++) { -unsigned j; -u32 pair_size =0 , tidsize; -/* -* This inner loop will program an entire group or the -* array of pinned pages (which ever limit is hit -* first). -*/ -for (j =0 ; j < dd->rcv_entries.group_size && - pmapped < pinned; j++, pmapped++, tid++) { - tidsize =PAGE_SIZE ; - phys[pmapped] =hfi1_map_page (dd->pcidev, - pages[pmapped],0 , - tidsize,PCI_DMA_FROMDEVICE ); -trace_hfi1_exp_rcv_set (uctxt->ctxt, - fd->subctxt, - tid, vaddr, - phys[pmapped], - pages[pmapped]); -/* -* Each RcvArray entry is programmed with one -* page * worth of memory. This will handle -* the 8K MTU as well as anything smaller -* due to the fact that both entries in the -* RcvTidPair are programmed with a page. -* PSM currently does not handle anything -* bigger than 8K MTU, so should we even worry -* about 10K here? -*/ -hfi1_put_tid (dd, tid,PT_EXPECTED , - phys[pmapped], -ilog2 (tidsize >>PAGE_SHIFT ) +1 ); - pair_size += tidsize >>PAGE_SHIFT ; -EXP_TID_RESET (tidlist[pairidx],LEN , pair_size); -if (!(tid %2 )) { - tidlist[pairidx] |= -EXP_TID_SET (IDX , - (tid - uctxt->expected_base) - /2 ); - tidlist[pairidx] |= -EXP_TID_SET (CTRL ,1 ); - tidcnt++; - }else { - tidlist[pairidx] |= -EXP_TID_SET (CTRL ,2 ); - pair_size =0 ; - pairidx++; - } - } -/* -* We've programmed the entire group (or as much of the -* group as we'll use. Now, it's time to push it out... -*/ -flush_wc (); - } - mapped += pinned; -atomic_set (&uctxt->tidcursor, - (((useidx &0xffffff ) <<16 ) | - ((bitidx + bits_used) &0xffffff ))); - } -trace_hfi1_exp_tid_map (uctxt->ctxt, fd->subctxt,0 , uctxt->tidusemap, - uctxt->tidmapcnt); - -done: -/* If we've mapped anything, copy relevant info to user */ -if (mapped) { -if (copy_to_user ((void __user *)(unsigned long )tinfo->tidlist, - tidlist,sizeof (tidlist[0 ]) * tidcnt)) { - ret = -EFAULT ; - goto done; - } -/* copy TID info to user */ -if (copy_to_user ((void __user *)(unsigned long )tinfo->tidmap, - tidmap,sizeof (tidmap[0 ]) * uctxt->tidmapcnt)) - ret = -EFAULT ; - } -bail: -/* -* Calculate mapped length. New Exp TID protocol does not "unwind" and -* report an error if it can't map the entire buffer. It just reports -* the length that was mapped. -*/ - tinfo->length = mapped *PAGE_SIZE ; - tinfo->tidcnt = tidcnt; -return ret; -} - -static int exp_tid_free (struct file *fp,struct hfi1_tid_info *tinfo) -{ -struct hfi1_filedata *fd = fp->private_data; -struct hfi1_ctxtdata *uctxt = fd->uctxt; -struct hfi1_devdata *dd = uctxt->dd; -unsigned long tidmap[uctxt->tidmapcnt]; -struct page **pages; -dma_addr_t *phys; -u16 idx, bitidx, tid; -int ret =0 ; - -if (copy_from_user (&tidmap, (void __user *)(unsigned long ) - tinfo->tidmap, -sizeof (tidmap[0 ]) * uctxt->tidmapcnt)) { - ret = -EFAULT ; - goto done; - } -for (idx =0 ; idx < uctxt->tidmapcnt; idx++) { -unsigned long map; - - bitidx =0 ; -if (!tidmap[idx]) -continue ; - map = tidmap[idx]; -while ((bitidx =tzcnt (map)) <BITS_PER_LONG ) { -int i, pcount =0 ; -struct page *pshadow[dd->rcv_entries.group_size]; -unsigned offset = ((idx *BITS_PER_LONG ) + bitidx) * - dd->rcv_entries.group_size; - - pages = uctxt->tid_pg_list + offset; - phys = uctxt->physshadow + offset; - tid = uctxt->expected_base + offset; -for (i =0 ; i < dd->rcv_entries.group_size; - i++, tid++) { -if (pages[i]) { -hfi1_put_tid (dd, tid,PT_INVALID , -0 ,0 ); -trace_hfi1_exp_rcv_free (uctxt->ctxt, - fd->subctxt, - tid, phys[i], - pages[i]); -pci_unmap_page (dd->pcidev, phys[i], -PAGE_SIZE ,PCI_DMA_FROMDEVICE ); - pshadow[pcount] = pages[i]; - pages[i] =NULL ; - pcount++; - phys[i] =0 ; - } - } -flush_wc (); -hfi1_release_user_pages (pshadow, pcount); -clear_bit (bitidx, &uctxt->tidusemap[idx]); - map &= ~(1ULL <<bitidx); - } - } -trace_hfi1_exp_tid_map (uctxt->ctxt, fd->subctxt,1 , uctxt->tidusemap, - uctxt->tidmapcnt); -done: -return ret; -} - -static void unlock_exp_tids (struct hfi1_ctxtdata *uctxt) -{ -struct hfi1_devdata *dd = uctxt->dd; -unsigned tid; - -dd_dev_info (dd,"ctxt %u unlocking any locked expTID pages\n" , - uctxt->ctxt); -for (tid =0 ; tid < uctxt->expected_count; tid++) { -struct page *p = uctxt->tid_pg_list[tid]; -dma_addr_t phys; - -if (!p) -continue ; - - phys = uctxt->physshadow[tid]; - uctxt->physshadow[tid] =0 ; - uctxt->tid_pg_list[tid] =NULL ; -pci_unmap_page (dd->pcidev, phys,PAGE_SIZE ,PCI_DMA_FROMDEVICE ); -hfi1_release_user_pages (&p,1 ); - } -} -static int set_ctxt_pkey (struct hfi1_ctxtdata *uctxt,unsigned subctxt,u16 pkey) {
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.
@@ -942,13 +942,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 +867 -7
923 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
@@ -1059,6 +1059,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);
@@ -1088,6 +1094,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]);
include/uapi/rdma/hfi/hfi1_user.h +6 -8
@@ -66,7 +66,7 @@* The major version changes when data structures change in an incompatible * way. The driver must be the same for initialization to succeed. */ -#define HFI1_USER_SWMAJOR 4 +#define HFI1_USER_SWMAJOR 5/* * Minor version differences are always compatible
@@ -93,7 +93,7 @@#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 */ #define HFI1_CAP_NODROP_EGR_FULL (1UL << 9)/* Don't drop on EGR buffs full */ -#define HFI1_CAP_TID_UNMAP (1UL << 10)/* Enable Expected TID caching */ +#define HFI1_CAP_TID_UNMAP (1UL << 10)/* Disable Expected TID caching */ #define HFI1_CAP_PRINT_UNIMPL (1UL << 11)/* Show for unimplemented feats */ #define HFI1_CAP_ALLOW_PERM_JKEY (1UL << 12)/* Allow use of permissive JKEY */ #define HFI1_CAP_NO_INTEGRITY (1UL << 13)/* Enable ctxt integrity checks */
@@ -134,6 +134,7 @@#define HFI1_CMD_ACK_EVENT 10/* ack & clear user status bits */ #define HFI1_CMD_SET_PKEY 11/* set context's pkey */ #define HFI1_CMD_CTXT_RESET 12/* reset context's HW send context */ +#define HFI1_CMD_TID_INVAL_READ 13/* read TID cache invalidations */ /* separate EPROM commands from normal PSM commands */ #define HFI1_CMD_EP_INFO 64/* read EPROM device ID */ #define HFI1_CMD_EP_ERASE_CHIP 65/* erase whole EPROM */
@@ -149,13 +150,15 @@#define _HFI1_EVENT_LID_CHANGE_BIT 2#define _HFI1_EVENT_LMC_CHANGE_BIT 3#define _HFI1_EVENT_SL2VL_CHANGE_BIT 4 -#define _HFI1_MAX_EVENT_BIT _HFI1_EVENT_SL2VL_CHANGE_BIT +#define _HFI1_EVENT_TID_MMU_NOTIFY_BIT 5 +#define _HFI1_MAX_EVENT_BIT _HFI1_EVENT_TID_MMU_NOTIFY_BIT#define HFI1_EVENT_FROZEN (1UL << _HFI1_EVENT_FROZEN_BIT)#define HFI1_EVENT_LINKDOWN (1UL << _HFI1_EVENT_LINKDOWN_BIT)#define HFI1_EVENT_LID_CHANGE (1UL << _HFI1_EVENT_LID_CHANGE_BIT)#define HFI1_EVENT_LMC_CHANGE (1UL << _HFI1_EVENT_LMC_CHANGE_BIT)#define HFI1_EVENT_SL2VL_CHANGE (1UL << _HFI1_EVENT_SL2VL_CHANGE_BIT) +#define HFI1_EVENT_TID_MMU_NOTIFY (1UL << _HFI1_EVENT_TID_MMU_NOTIFY_BIT)/* * These are the status bits readable (in ASCII form, 64bit value)
@@ -240,11 +243,6 @@ struct hfi1_tid_info {__u32 tidcnt;/* length of transfer buffer programmed by this request */ __u32 length; -/* -* pointer to bitmap of TIDs used for this call; -* checked for being large enough at open -*/ -__u64 tidmap; };struct hfi1_cmd {
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): 1446245928-12675-7-git-send-email-ira.weiny-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org
Re: [PATCH v4 6/9] staging/rdma/hfi1: Implement Expected Receive TID caching
Quoted 58 lines · On Fri, Oct 30, 2015 at 06:58:45PM -0400…
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 V3:
Reworked based on the removal of the file pointer macros Split out some prep patches and code clean upChanges 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 9 lines
drivers/staging/rdma/hfi1/file_ops.c | 469 ++--------------- 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 | 874 ++++++++++++++++++++++++++++++- drivers/staging/rdma/hfi1/user_pages.c | 110 +--- drivers/staging/rdma/hfi1/user_sdma.c | 13 + include/uapi/rdma/hfi/hfi1_user.h | 14 +- 8 files changed, 1069 insertions(+), 591 deletions(-)
This is still a really big patch, any chance you can break it up into smaller, reviewable parts? I see you add different operations, perhaps break it up into one patch per logical thing?
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 v4 6/9] staging/rdma/hfi1: Implement Expected Receive TID caching
Quoted 69 lines · Greg KH
Quoted 58 lines · On Fri, Oct 30, 2015 at 06:58:45PM -0400…
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 V3:
Reworked based on the removal of the file pointer macros Split out some prep patches and code clean upChanges 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 commentsQuoted 9 lines
drivers/staging/rdma/hfi1/file_ops.c | 469 ++--------------- 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 | 874 ++++++++++++++++++++++++++++++- drivers/staging/rdma/hfi1/user_pages.c | 110 +--- drivers/staging/rdma/hfi1/user_sdma.c | 13 + include/uapi/rdma/hfi/hfi1_user.h | 14 +- 8 files changed, 1069 insertions(+), 591 deletions(-)
Quoted 4 lines
This is still a really big patch, any chance you can break it up into smaller, reviewable parts? I see you add different operations, perhaps break it up into one patch per logical thing?
I understand, however, as you have seen with my attempt to break this up there are issues if we do so.
I need to clean up the previous patch which was an attempt to split this one up. But at this point I would really like to preserve the functionality we have here. Breaking this up beyond this point is going to be difficult to do and really will not allow for bisecting the code across this feature being in vs out.
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
PATCH v4 7/9 staging/rdma/hfi1: move hfi1_migrate_qp
In reply to a message not in the archiveFrom: Mike Marciniszyn <[email protected]>
Move hfi1_migrate_qp from ruc.c to qp.[hc] in prep for modifying the QP workqueue.
--- drivers/staging/rdma/hfi1/qp.c | 20 ++++++++++++++++++++ drivers/staging/rdma/hfi1/qp.h | 2 ++ drivers/staging/rdma/hfi1/ruc.c | 20 -------------------- drivers/staging/rdma/hfi1/verbs.h | 2 -- 4 files changed, 22 insertions(+), 22 deletions(-)
drivers/staging/rdma/hfi1/qp.c +20 -0
@@ -1685,3 +1685,23 @@ void qp_comm_est(struct hfi1_qp *qp) qp->ibqp.event_handler (&ev, qp->ibqp.qp_context); } } + +/* +* 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); +}
drivers/staging/rdma/hfi1/qp.h +2 -0
@@ -247,4 +247,6 @@ void qp_iter_print(struct seq_file *s, struct qp_iter *iter);*/ void qp_comm_est (struct hfi1_qp *qp); +void hfi1_migrate_qp (struct hfi1_qp *qp); +#endif /* _QP_H */
drivers/staging/rdma/hfi1/ruc.c +0 -20
@@ -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) {
drivers/staging/rdma/hfi1/verbs.h +0 -2
@@ -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
PATCH v4 8/9 staging/rdma/hfi1: Use parallel workqueue for SDMA engines
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.
Use alloc_workqueue with a workqueue limit of the number of sdma engines and with WQ_CPU_INTENSIVE and WQ_HIGHPRI specified.
Then change send to use the new scheduler which no longer needs to get the s_lock
---
Changes from v3:
Split patch out code refactoring and separate functionality
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.h | 35 +++++++++++++++++++++++++++++++++++ drivers/staging/rdma/hfi1/sdma.c | 8 +++++--- drivers/staging/rdma/hfi1/sdma.h | 8 +++++--- drivers/staging/rdma/hfi1/verbs.c | 20 ++++---------------- drivers/staging/rdma/hfi1/verbs.h | 1 - 8 files changed, 60 insertions(+), 32 deletions(-)
drivers/staging/rdma/hfi1/chip.c +1 -0
@@ -9018,6 +9018,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.h +35 -0
@@ -247,6 +247,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/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; }
@@ -1874,7 +1875,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
@@ -1894,6 +1895,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/verbs.c +4 -16
@@ -162,6 +162,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. */
@@ -497,9 +499,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;
@@ -2125,20 +2127,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 +0 -1
@@ -841,7 +841,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);
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 v4 9/9 staging/rdma/hfi: pre-compute sc and sde for RC/UC QPs
In reply to a message not in the archiveFrom: Mike Marciniszyn <[email protected]>
Now that we have a multi-threaded work queue we precomputed and store the SC and SDE on RC and UC QPs for faster access.
--- drivers/staging/rdma/hfi1/qp.c | 27 +++++++++++++++++++++------ drivers/staging/rdma/hfi1/qp.h | 1 - drivers/staging/rdma/hfi1/ruc.c | 10 ++-------- drivers/staging/rdma/hfi1/ud.c | 1 + drivers/staging/rdma/hfi1/verbs.c | 14 +++----------- drivers/staging/rdma/hfi1/verbs.h | 3 ++- 6 files changed, 29 insertions(+), 27 deletions(-)
drivers/staging/rdma/hfi1/qp.c +21 -6
@@ -617,7 +617,7 @@ int hfi1_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,int mig =0 ;int ret;u32 pmtu =0 ;/* for gcc warning only */ -struct hfi1_devdata *dd; +struct hfi1_devdata *dd =dd_from_dev (dev);spin_lock_irq (&qp->r_lock);spin_lock (&qp->s_lock);
@@ -631,23 +631,35 @@ int hfi1_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, goto inval;if (attr_mask &IB_QP_AV ) { +u8 sc; +if (attr->ah_attr.dlid >=HFI1_MULTICAST_LID_BASE ) goto inval;if (hfi1_check_ah (qp->ibqp.device, &attr->ah_attr)) goto inval; + sc =ah_to_sc (ibqp->device, &attr->ah_attr); +if (!qp_to_sdma_engine (qp, sc) && + dd->flags &HFI1_HAS_SEND_DMA ) + goto inval; }if (attr_mask &IB_QP_ALT_PATH ) { +u8 sc; +if (attr->alt_ah_attr.dlid >=HFI1_MULTICAST_LID_BASE ) goto inval;if (hfi1_check_ah (qp->ibqp.device, &attr->alt_ah_attr)) goto inval; -if (attr->alt_pkey_index >=hfi1_get_npkeys (dd_from_dev (dev))) +if (attr->alt_pkey_index >=hfi1_get_npkeys (dd)) + goto inval; + sc =ah_to_sc (ibqp->device, &attr->alt_ah_attr); +if (!qp_to_sdma_engine (qp, sc) && + dd->flags &HFI1_HAS_SEND_DMA ) goto inval; }if (attr_mask &IB_QP_PKEY_INDEX ) -if (attr->pkey_index >=hfi1_get_npkeys (dd_from_dev (dev))) +if (attr->pkey_index >=hfi1_get_npkeys (dd)) goto inval;if (attr_mask &IB_QP_MIN_RNR_TIMER )
@@ -792,6 +804,8 @@ int hfi1_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, qp->remote_ah_attr = attr->ah_attr; qp->s_srate = attr->ah_attr.static_rate; qp->srate_mbps =ib_rate_to_mbps (qp->s_srate); + qp->s_sc =ah_to_sc (ibqp->device, &qp->remote_ah_attr); + qp->s_sde =qp_to_sdma_engine (qp, qp->s_sc); }if (attr_mask &IB_QP_ALT_PATH ) {
@@ -806,6 +820,8 @@ int hfi1_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *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 ; + qp->s_sc =ah_to_sc (ibqp->device, &qp->remote_ah_attr); + qp->s_sde =qp_to_sdma_engine (qp, qp->s_sc); } }
@@ -1528,9 +1544,6 @@ struct sdma_engine *qp_to_sdma_engine(struct hfi1_qp *qp, u8 sc5)if (!(dd->flags &HFI1_HAS_SEND_DMA ))return NULL ;switch (qp->ibqp.qp_type) { -case IB_QPT_UC : -case IB_QPT_RC : -break ;case IB_QPT_SMI :return NULL ;default :
@@ -1699,6 +1712,8 @@ void hfi1_migrate_qp(struct hfi1_qp *qp) 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 ; + qp->s_sc =ah_to_sc (qp->ibqp.device, &qp->remote_ah_attr); + qp->s_sde =qp_to_sdma_engine (qp, qp->s_sc); ev.device = qp->ibqp.device; ev.element.qp = &qp->ibqp;
drivers/staging/rdma/hfi1/qp.h +0 -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 ; }/**
drivers/staging/rdma/hfi1/ruc.c +2 -8
@@ -694,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 ;
@@ -741,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. */
@@ -755,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/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 +3 -11
@@ -999,7 +999,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;
@@ -1020,12 +1019,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);
@@ -1040,17 +1034,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 ;
drivers/staging/rdma/hfi1/verbs.h +2 -1
@@ -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;
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