cxlflash: Reorder user context initialization
authorUma Krishnan <ukrishn@linux.vnet.ibm.com>
Fri, 4 Mar 2016 21:55:18 +0000 (15:55 -0600)
committerMartin K. Petersen <martin.petersen@oracle.com>
Wed, 9 Mar 2016 02:17:33 +0000 (21:17 -0500)
In order to support cxlflash in the PowerVM environment, underlying
hypervisor APIs have imposed a kernel API ordering change.

For the superpipe access to LUN, user applications need a context.
The cxlflash module creates this context by making a sequence of
cxl calls. In the current code, a context is initialized via
cxl_dev_context_init() followed by cxl_process_element(), a function
that obtains the process element id. Finally, cxl_start_work()
is called to attach the process element.

In the PowerVM environment, a process element id cannot be obtained
from the hypervisor until the process element is attached. The
cxlflash module is unable to create contexts without a valid
process element id.

To fix this problem, cxl_start_work() is called before obtaining
the process element id.

Signed-off-by: Uma Krishnan <ukrishn@linux.vnet.ibm.com>
Acked-by: Matthew R. Ochs <mrochs@linux.vnet.ibm.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/cxlflash/superpipe.c

index 7ec0b7a92876cfbf4cc1eb1e162a4e0942253023..d8a5cb3cd2bd370d910db23cce23b6a13526e421 100644 (file)
@@ -1386,6 +1386,13 @@ static int cxlflash_disk_attach(struct scsi_device *sdev,
                goto out_attach;
        }
 
+       ctxi = create_context(cfg);
+       if (unlikely(!ctxi)) {
+               dev_err(dev, "%s: Failed to create context! (%d)\n",
+                       __func__, ctxid);
+               goto err;
+       }
+
        ctx = cxl_dev_context_init(cfg->dev);
        if (IS_ERR_OR_NULL(ctx)) {
                dev_err(dev, "%s: Could not initialize context %p\n",
@@ -1394,6 +1401,17 @@ static int cxlflash_disk_attach(struct scsi_device *sdev,
                goto err;
        }
 
+       work = &ctxi->work;
+       work->num_interrupts = attach->num_interrupts;
+       work->flags = CXL_START_WORK_NUM_IRQS;
+
+       rc = cxl_start_work(ctx, work);
+       if (unlikely(rc)) {
+               dev_dbg(dev, "%s: Could not start context rc=%d\n",
+                       __func__, rc);
+               goto err;
+       }
+
        ctxid = cxl_process_element(ctx);
        if (unlikely((ctxid >= MAX_CONTEXT) || (ctxid < 0))) {
                dev_err(dev, "%s: ctxid (%d) invalid!\n", __func__, ctxid);
@@ -1411,27 +1429,9 @@ static int cxlflash_disk_attach(struct scsi_device *sdev,
        /* Translate read/write O_* flags from fcntl.h to AFU permission bits */
        perms = SISL_RHT_PERM(attach->hdr.flags + 1);
 
-       ctxi = create_context(cfg);
-       if (unlikely(!ctxi)) {
-               dev_err(dev, "%s: Failed to create context! (%d)\n",
-                       __func__, ctxid);
-               goto err;
-       }
-
        /* Context mutex is locked upon return */
        init_context(ctxi, cfg, ctx, ctxid, fd, file, perms);
 
-       work = &ctxi->work;
-       work->num_interrupts = attach->num_interrupts;
-       work->flags = CXL_START_WORK_NUM_IRQS;
-
-       rc = cxl_start_work(ctx, work);
-       if (unlikely(rc)) {
-               dev_dbg(dev, "%s: Could not start context rc=%d\n",
-                       __func__, rc);
-               goto err;
-       }
-
        rc = afu_attach(cfg, ctxi);
        if (unlikely(rc)) {
                dev_err(dev, "%s: Could not attach AFU rc %d\n", __func__, rc);
@@ -1532,24 +1532,24 @@ static int recover_context(struct cxlflash_cfg *cfg, struct ctx_info *ctxi)
                goto out;
        }
 
+       rc = cxl_start_work(ctx, &ctxi->work);
+       if (unlikely(rc)) {
+               dev_dbg(dev, "%s: Could not start context rc=%d\n",
+                       __func__, rc);
+               goto err1;
+       }
+
        ctxid = cxl_process_element(ctx);
        if (unlikely((ctxid >= MAX_CONTEXT) || (ctxid < 0))) {
                dev_err(dev, "%s: ctxid (%d) invalid!\n", __func__, ctxid);
                rc = -EPERM;
-               goto err1;
+               goto err2;
        }
 
        file = cxl_get_fd(ctx, &cfg->cxl_fops, &fd);
        if (unlikely(fd < 0)) {
                rc = -ENODEV;
                dev_err(dev, "%s: Could not get file descriptor\n", __func__);
-               goto err1;
-       }
-
-       rc = cxl_start_work(ctx, &ctxi->work);
-       if (unlikely(rc)) {
-               dev_dbg(dev, "%s: Could not start context rc=%d\n",
-                       __func__, rc);
                goto err2;
        }
 
@@ -1594,10 +1594,10 @@ out:
        return rc;
 
 err3:
-       cxl_stop_context(ctx);
-err2:
        fput(file);
        put_unused_fd(fd);
+err2:
+       cxl_stop_context(ctx);
 err1:
        cxl_release_context(ctx);
        goto out;