aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthew R. Ochs <mrochs@linux.vnet.ibm.com>2016-03-04 16:55:16 -0500
committerMartin K. Petersen <martin.petersen@oracle.com>2016-03-08 21:17:33 -0500
commit5e6632d19ea2fafaec1b7c4cda7f7157ee8ad983 (patch)
tree083307c2211a29108de926d9d06722fdcb096d35
parent6ded8b3cbd9a6254da5a38f35e20aa3c316d9092 (diff)
cxlflash: Split out context initialization
Presently, context information structures are allocated and initialized in the same routine, create_context(). This imposes an ordering restriction such that all pieces of information needed to initialize a context must be known before the context is even allocated. This design point is not flexible when the order of context creation needs to be modified. Specifically, this can lead to problems when members of the context information structure are a part of an ordering dependency (i.e. - the 'work' structure embedded within the context). To remedy, the allocation is left as-is, inside of the existing create_context() routine and the initialization is transitioned to a new void routine, init_context(). At the same time, in anticipation of these routines not being called in sequence, a state boolean is added to the context information structure to track when the context has been initilized. The context teardown routine, destroy_context(), is modified to support being called with a non-initialized context. Signed-off-by: Matthew R. Ochs <mrochs@linux.vnet.ibm.com> Reviewed-by: Uma Krishnan <ukrishn@linux.vnet.ibm.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
-rw-r--r--drivers/scsi/cxlflash/superpipe.c92
-rw-r--r--drivers/scsi/cxlflash/superpipe.h1
2 files changed, 56 insertions, 37 deletions
diff --git a/drivers/scsi/cxlflash/superpipe.c b/drivers/scsi/cxlflash/superpipe.c
index f4020dbb55c3..b30b362318fa 100644
--- a/drivers/scsi/cxlflash/superpipe.c
+++ b/drivers/scsi/cxlflash/superpipe.c
@@ -709,27 +709,32 @@ int cxlflash_disk_release(struct scsi_device *sdev,
709 * @cfg: Internal structure associated with the host. 709 * @cfg: Internal structure associated with the host.
710 * @ctxi: Context to release. 710 * @ctxi: Context to release.
711 * 711 *
712 * Note that the rht_lun member of the context was cut from a single 712 * This routine is safe to be called with a a non-initialized context
713 * allocation when the context was created and therefore does not need 713 * and is tolerant of being called with the context's mutex held (it
714 * to be explicitly freed. Also note that we conditionally check for the 714 * will be unlocked if necessary before freeing). Also note that the
715 * existence of the context control map before clearing the RHT registers 715 * routine conditionally checks for the existence of the context control
716 * and context capabilities because it is possible to destroy a context 716 * map before clearing the RHT registers and context capabilities because
717 * while the context is in the error state (previous mapping was removed 717 * it is possible to destroy a context while the context is in the error
718 * [so we don't have to worry about clearing] and context is waiting for 718 * state (previous mapping was removed [so there is no need to worry about
719 * a new mapping). 719 * clearing] and context is waiting for a new mapping).
720 */ 720 */
721static void destroy_context(struct cxlflash_cfg *cfg, 721static void destroy_context(struct cxlflash_cfg *cfg,
722 struct ctx_info *ctxi) 722 struct ctx_info *ctxi)
723{ 723{
724 struct afu *afu = cfg->afu; 724 struct afu *afu = cfg->afu;
725 725
726 WARN_ON(!list_empty(&ctxi->luns)); 726 if (ctxi->initialized) {
727 WARN_ON(!list_empty(&ctxi->luns));
727 728
728 /* Clear RHT registers and drop all capabilities for this context */ 729 /* Clear RHT registers and drop all capabilities for context */
729 if (afu->afu_map && ctxi->ctrl_map) { 730 if (afu->afu_map && ctxi->ctrl_map) {
730 writeq_be(0, &ctxi->ctrl_map->rht_start); 731 writeq_be(0, &ctxi->ctrl_map->rht_start);
731 writeq_be(0, &ctxi->ctrl_map->rht_cnt_id); 732 writeq_be(0, &ctxi->ctrl_map->rht_cnt_id);
732 writeq_be(0, &ctxi->ctrl_map->ctx_cap); 733 writeq_be(0, &ctxi->ctrl_map->ctx_cap);
734 }
735
736 if (mutex_is_locked(&ctxi->mutex))
737 mutex_unlock(&ctxi->mutex);
733 } 738 }
734 739
735 /* Free memory associated with context */ 740 /* Free memory associated with context */
@@ -742,23 +747,12 @@ static void destroy_context(struct cxlflash_cfg *cfg,
742/** 747/**
743 * create_context() - allocates and initializes a context 748 * create_context() - allocates and initializes a context
744 * @cfg: Internal structure associated with the host. 749 * @cfg: Internal structure associated with the host.
745 * @ctx: Previously obtained CXL context reference.
746 * @ctxid: Previously obtained process element associated with CXL context.
747 * @adap_fd: Previously obtained adapter fd associated with CXL context.
748 * @file: Previously obtained file associated with CXL context.
749 * @perms: User-specified permissions.
750 *
751 * The context's mutex is locked when an allocated context is returned.
752 * 750 *
753 * Return: Allocated context on success, NULL on failure 751 * Return: Allocated context on success, NULL on failure
754 */ 752 */
755static struct ctx_info *create_context(struct cxlflash_cfg *cfg, 753static struct ctx_info *create_context(struct cxlflash_cfg *cfg)
756 struct cxl_context *ctx, int ctxid,
757 int adap_fd, struct file *file,
758 u32 perms)
759{ 754{
760 struct device *dev = &cfg->dev->dev; 755 struct device *dev = &cfg->dev->dev;
761 struct afu *afu = cfg->afu;
762 struct ctx_info *ctxi = NULL; 756 struct ctx_info *ctxi = NULL;
763 struct llun_info **lli = NULL; 757 struct llun_info **lli = NULL;
764 u8 *ws = NULL; 758 u8 *ws = NULL;
@@ -781,28 +775,49 @@ static struct ctx_info *create_context(struct cxlflash_cfg *cfg,
781 ctxi->rht_lun = lli; 775 ctxi->rht_lun = lli;
782 ctxi->rht_needs_ws = ws; 776 ctxi->rht_needs_ws = ws;
783 ctxi->rht_start = rhte; 777 ctxi->rht_start = rhte;
784 ctxi->rht_perms = perms; 778out:
779 return ctxi;
780
781err:
782 kfree(ws);
783 kfree(lli);
784 kfree(ctxi);
785 ctxi = NULL;
786 goto out;
787}
788
789/**
790 * init_context() - initializes a previously allocated context
791 * @ctxi: Previously allocated context
792 * @cfg: Internal structure associated with the host.
793 * @ctx: Previously obtained CXL context reference.
794 * @ctxid: Previously obtained process element associated with CXL context.
795 * @adap_fd: Previously obtained adapter fd associated with CXL context.
796 * @file: Previously obtained file associated with CXL context.
797 * @perms: User-specified permissions.
798 *
799 * Upon return, the context is marked as initialized and the context's mutex
800 * is locked.
801 */
802static void init_context(struct ctx_info *ctxi, struct cxlflash_cfg *cfg,
803 struct cxl_context *ctx, int ctxid, int adap_fd,
804 struct file *file, u32 perms)
805{
806 struct afu *afu = cfg->afu;
785 807
808 ctxi->rht_perms = perms;
786 ctxi->ctrl_map = &afu->afu_map->ctrls[ctxid].ctrl; 809 ctxi->ctrl_map = &afu->afu_map->ctrls[ctxid].ctrl;
787 ctxi->ctxid = ENCODE_CTXID(ctxi, ctxid); 810 ctxi->ctxid = ENCODE_CTXID(ctxi, ctxid);
788 ctxi->lfd = adap_fd; 811 ctxi->lfd = adap_fd;
789 ctxi->pid = current->tgid; /* tgid = pid */ 812 ctxi->pid = current->tgid; /* tgid = pid */
790 ctxi->ctx = ctx; 813 ctxi->ctx = ctx;
791 ctxi->file = file; 814 ctxi->file = file;
815 ctxi->initialized = true;
792 mutex_init(&ctxi->mutex); 816 mutex_init(&ctxi->mutex);
793 INIT_LIST_HEAD(&ctxi->luns); 817 INIT_LIST_HEAD(&ctxi->luns);
794 INIT_LIST_HEAD(&ctxi->list); /* initialize for list_empty() */ 818 INIT_LIST_HEAD(&ctxi->list); /* initialize for list_empty() */
795 819
796 mutex_lock(&ctxi->mutex); 820 mutex_lock(&ctxi->mutex);
797out:
798 return ctxi;
799
800err:
801 kfree(ws);
802 kfree(lli);
803 kfree(ctxi);
804 ctxi = NULL;
805 goto out;
806} 821}
807 822
808/** 823/**
@@ -1396,13 +1411,16 @@ static int cxlflash_disk_attach(struct scsi_device *sdev,
1396 /* Translate read/write O_* flags from fcntl.h to AFU permission bits */ 1411 /* Translate read/write O_* flags from fcntl.h to AFU permission bits */
1397 perms = SISL_RHT_PERM(attach->hdr.flags + 1); 1412 perms = SISL_RHT_PERM(attach->hdr.flags + 1);
1398 1413
1399 ctxi = create_context(cfg, ctx, ctxid, fd, file, perms); 1414 ctxi = create_context(cfg);
1400 if (unlikely(!ctxi)) { 1415 if (unlikely(!ctxi)) {
1401 dev_err(dev, "%s: Failed to create context! (%d)\n", 1416 dev_err(dev, "%s: Failed to create context! (%d)\n",
1402 __func__, ctxid); 1417 __func__, ctxid);
1403 goto err3; 1418 goto err3;
1404 } 1419 }
1405 1420
1421 /* Context mutex is locked upon return */
1422 init_context(ctxi, cfg, ctx, ctxid, fd, file, perms);
1423
1406 work = &ctxi->work; 1424 work = &ctxi->work;
1407 work->num_interrupts = attach->num_interrupts; 1425 work->num_interrupts = attach->num_interrupts;
1408 work->flags = CXL_START_WORK_NUM_IRQS; 1426 work->flags = CXL_START_WORK_NUM_IRQS;
diff --git a/drivers/scsi/cxlflash/superpipe.h b/drivers/scsi/cxlflash/superpipe.h
index bede574bcd77..5f9a091fda95 100644
--- a/drivers/scsi/cxlflash/superpipe.h
+++ b/drivers/scsi/cxlflash/superpipe.h
@@ -102,6 +102,7 @@ struct ctx_info {
102 u64 ctxid; 102 u64 ctxid;
103 int lfd; 103 int lfd;
104 pid_t pid; 104 pid_t pid;
105 bool initialized;
105 bool unavail;