Merge tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dledford/rdma
[cascardo/linux.git] / drivers / infiniband / hw / hfi1 / file_ops.c
index b80c8d2..7e03ccd 100644 (file)
@@ -168,6 +168,7 @@ static inline int is_valid_mmap(u64 token)
 
 static int hfi1_file_open(struct inode *inode, struct file *fp)
 {
+       struct hfi1_filedata *fd;
        struct hfi1_devdata *dd = container_of(inode->i_cdev,
                                               struct hfi1_devdata,
                                               user_cdev);
@@ -176,10 +177,18 @@ static int hfi1_file_open(struct inode *inode, struct file *fp)
        kobject_get(&dd->kobj);
 
        /* 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;
-       return fp->private_data ? 0 : -ENOMEM;
+
+       fd = kzalloc(sizeof(*fd), GFP_KERNEL);
+
+       if (fd) {
+               fd->rec_cpu_num = -1; /* no cpu affinity by default */
+               fd->mm = current->mm;
+               atomic_inc(&fd->mm->mm_count);
+       }
+
+       fp->private_data = fd;
+
+       return fd ? 0 : -ENOMEM;
 }
 
 static long hfi1_file_ioctl(struct file *fp, unsigned int cmd,
@@ -214,7 +223,7 @@ static long hfi1_file_ioctl(struct file *fp, unsigned int cmd,
                ret = assign_ctxt(fp, &uinfo);
                if (ret < 0)
                        return ret;
-               setup_ctxt(fp);
+               ret = setup_ctxt(fp);
                if (ret)
                        return ret;
                ret = user_init(fp);
@@ -228,7 +237,7 @@ static long hfi1_file_ioctl(struct file *fp, unsigned int cmd,
                                    sizeof(struct hfi1_base_info));
                break;
        case HFI1_IOCTL_CREDIT_UPD:
-               if (uctxt && uctxt->sc)
+               if (uctxt)
                        sc_return_credits(uctxt->sc);
                break;
 
@@ -771,6 +780,7 @@ static int hfi1_file_close(struct inode *inode, struct file *fp)
        mutex_unlock(&hfi1_mutex);
        hfi1_free_ctxtdata(dd, uctxt);
 done:
+       mmdrop(fdata->mm);
        kobject_put(&dd->kobj);
        kfree(fdata);
        return 0;
@@ -975,7 +985,7 @@ static int allocate_ctxt(struct file *fp, struct hfi1_devdata *dd,
                        return ret;
        }
        uctxt->userversion = uinfo->userversion;
-       uctxt->flags = HFI1_CAP_UGET(MASK);
+       uctxt->flags = hfi1_cap_mask; /* save current flag state */
        init_waitqueue_head(&uctxt->wait);
        strlcpy(uctxt->comm, current->comm, sizeof(uctxt->comm));
        memcpy(uctxt->uuid, uinfo->uuid, sizeof(uctxt->uuid));
@@ -1078,18 +1088,18 @@ static int user_init(struct file *fp)
        hfi1_set_ctxt_jkey(uctxt->dd, uctxt->ctxt, uctxt->jkey);
 
        rcvctrl_ops = HFI1_RCVCTRL_CTXT_ENB;
-       if (HFI1_CAP_KGET_MASK(uctxt->flags, HDRSUPP))
+       if (HFI1_CAP_UGET_MASK(uctxt->flags, HDRSUPP))
                rcvctrl_ops |= HFI1_RCVCTRL_TIDFLOW_ENB;
        /*
         * Ignore the bit in the flags for now until proper
         * support for multiple packet per rcv array entry is
         * added.
         */
-       if (!HFI1_CAP_KGET_MASK(uctxt->flags, MULTI_PKT_EGR))
+       if (!HFI1_CAP_UGET_MASK(uctxt->flags, MULTI_PKT_EGR))
                rcvctrl_ops |= HFI1_RCVCTRL_ONE_PKT_EGR_ENB;
-       if (HFI1_CAP_KGET_MASK(uctxt->flags, NODROP_EGR_FULL))
+       if (HFI1_CAP_UGET_MASK(uctxt->flags, NODROP_EGR_FULL))
                rcvctrl_ops |= HFI1_RCVCTRL_NO_EGR_DROP_ENB;
-       if (HFI1_CAP_KGET_MASK(uctxt->flags, NODROP_RHQ_FULL))
+       if (HFI1_CAP_UGET_MASK(uctxt->flags, NODROP_RHQ_FULL))
                rcvctrl_ops |= HFI1_RCVCTRL_NO_RHQ_DROP_ENB;
        /*
         * The RcvCtxtCtrl.TailUpd bit has to be explicitly written.
@@ -1097,7 +1107,7 @@ static int user_init(struct file *fp)
         * uses of the chip or ctxt. Therefore, add the rcvctrl op
         * for both cases.
         */
-       if (HFI1_CAP_KGET_MASK(uctxt->flags, DMA_RTAIL))
+       if (HFI1_CAP_UGET_MASK(uctxt->flags, DMA_RTAIL))
                rcvctrl_ops |= HFI1_RCVCTRL_TAILUPD_ENB;
        else
                rcvctrl_ops |= HFI1_RCVCTRL_TAILUPD_DIS;
@@ -1120,9 +1130,14 @@ static int get_ctxt_info(struct file *fp, void __user *ubase, __u32 len)
        int ret = 0;
 
        memset(&cinfo, 0, sizeof(cinfo));
-       ret = hfi1_get_base_kinfo(uctxt, &cinfo);
-       if (ret < 0)
-               goto done;
+       cinfo.runtime_flags = (((uctxt->flags >> HFI1_CAP_MISC_SHIFT) &
+                               HFI1_CAP_MISC_MASK) << HFI1_CAP_USER_SHIFT) |
+                       HFI1_CAP_UGET_MASK(uctxt->flags, MASK) |
+                       HFI1_CAP_KGET_MASK(uctxt->flags, K2U);
+       /* adjust flag if this fd is not able to cache */
+       if (!fd->handler)
+               cinfo.runtime_flags |= HFI1_CAP_TID_UNMAP; /* no caching */
+
        cinfo.num_active = hfi1_count_active_units();
        cinfo.unit = uctxt->dd->unit;
        cinfo.ctxt = uctxt->ctxt;
@@ -1144,7 +1159,7 @@ static int get_ctxt_info(struct file *fp, void __user *ubase, __u32 len)
        trace_hfi1_ctxt_info(uctxt->dd, uctxt->ctxt, fd->subctxt, cinfo);
        if (copy_to_user(ubase, &cinfo, sizeof(cinfo)))
                ret = -EFAULT;
-done:
+
        return ret;
 }