From: Uma Krishnan <hidden> Date: 2018-03-26 16:29:19
This patch series adds OCXL support to the cxlflash driver. With this
support, new devices using the OCXL transport will be supported by the
cxlflash driver along with the existing CXL devices. An effort is made
to keep this transport specific function independent of the existing
core driver that communicates with the AFU.
The first three patches contain a minor fix and staging improvements.
This series is intended for 4.17 and is bisectable.
v3 Changes:
- Addressed comments by Frederic Barrat
- Resolved IDR initialization bug
- Properly identify functions that do not have an AFU defined
- Added 3 new patches to the end of the series which resolve corner cases
v2 Changes:
- Replaced OpenCXL with OCXL in the commit messages and comments
Matthew R. Ochs (1):
cxlflash: Avoid clobbering context control register value
Uma Krishnan (40):
cxlflash: Preserve number of interrupts for master contexts
cxlflash: Add argument identifier names
cxlflash: Introduce OCXL backend
cxlflash: Hardware AFU for OCXL
cxlflash: Read host function configuration
cxlflash: Setup function acTag range
cxlflash: Read host AFU configuration
cxlflash: Setup AFU acTag range
cxlflash: Setup AFU PASID
cxlflash: Adapter context support for OCXL
cxlflash: Use IDR to manage adapter contexts
cxlflash: Support adapter file descriptors for OCXL
cxlflash: Support adapter context discovery
cxlflash: Support image reload policy modification
cxlflash: MMIO map the AFU
cxlflash: Support starting an adapter context
cxlflash: Support process specific mappings
cxlflash: Support AFU state toggling
cxlflash: Support reading adapter VPD data
cxlflash: Setup function OCXL link
cxlflash: Setup OCXL transaction layer
cxlflash: Support process element lifecycle
cxlflash: Support AFU interrupt management
cxlflash: Support AFU interrupt mapping and registration
cxlflash: Support starting user contexts
cxlflash: Support adapter context polling
cxlflash: Support adapter context reading
cxlflash: Support adapter context mmap and release
cxlflash: Support file descriptor mapping
cxlflash: Introduce object handle fop
cxlflash: Setup LISNs for user contexts
cxlflash: Setup LISNs for master contexts
cxlflash: Update synchronous interrupt status bits
cxlflash: Introduce OCXL context state machine
cxlflash: Register for translation errors
cxlflash: Support AFU reset
cxlflash: Enable OCXL operations
cxlflash: Synchronize reset and remove ops
cxlflash: Remove commmands from pending list on timeout
cxlflash: Handle spurious interrupts
drivers/scsi/cxlflash/Kconfig | 2 +-
drivers/scsi/cxlflash/Makefile | 2 +-
drivers/scsi/cxlflash/backend.h | 50 +-
drivers/scsi/cxlflash/common.h | 11 +-
drivers/scsi/cxlflash/cxl_hw.c | 13 +
drivers/scsi/cxlflash/main.c | 86 ++-
drivers/scsi/cxlflash/main.h | 1 +
drivers/scsi/cxlflash/ocxl_hw.c | 1436 +++++++++++++++++++++++++++++++++++++
drivers/scsi/cxlflash/ocxl_hw.h | 77 ++
drivers/scsi/cxlflash/sislite.h | 41 +-
drivers/scsi/cxlflash/superpipe.c | 14 +
11 files changed, 1682 insertions(+), 51 deletions(-)
create mode 100644 drivers/scsi/cxlflash/ocxl_hw.c
create mode 100644 drivers/scsi/cxlflash/ocxl_hw.h
--
2.1.0
From: Uma Krishnan <hidden> Date: 2018-03-26 16:29:56
The number of interrupts requested for user contexts are stored in the
context specific structures and utilized to manage the interrupts. For the
master contexts, this number is only used once and therefore not saved.
To prepare for future commits where the number of interrupts will be
required in more than one place, preserve the value in the master context
structure.
Signed-off-by: Uma Krishnan <redacted>
Acked-by: Matthew R. Ochs <redacted>
---
drivers/scsi/cxlflash/common.h | 1 +
drivers/scsi/cxlflash/main.c | 11 ++++++++---
2 files changed, 9 insertions(+), 3 deletions(-)
@@ -211,6 +211,7 @@ struct hwq {structsisl_ctrl_map__iomem*ctrl_map;/* MC control map */ctx_hndl_tctx_hndl;/* master's context handle */u32index;/* Index of this hwq */+intnum_irqs;/* Numer of interrupts requested for context */structlist_headpending_cmds;/* Commands pending completion */atomic_thsq_credits;
@@ -1982,6 +1986,7 @@ static int init_mc(struct cxlflash_cfg *cfg, u32 index)WARN_ON(hwq->ctx_cookie);hwq->ctx_cookie=ctx;+hwq->num_irqs=num_irqs;/* Set it up as a master with the CXL */cfg->ops->set_master(ctx);
From: Uma Krishnan <hidden> Date: 2018-03-26 16:30:22
From: "Matthew R. Ochs" <redacted>
The SISLite specification originally defined the context control
register with a single field of bits to represent the LISN and
also stipulated that the register reset value be 0. The cxlflash
driver took advantage of this when programming the LISN for the
master contexts via an unconditional write - no other bits were
preserved.
When unmap support was added, SISLite was updated to define bit
0 of the context control register as a way for the AFU to notify
the context owner that unmap operations were supported. Thus the
assumptions under which the register is setup changed and the
existing unconditional write is clobbering the unmap state for
master contexts. This is presently not an issue due to the order
in which the context control register is programmed in relation to
the unmap bit being queried but should be addressed to avoid a
future regression in the event this code is moved elsewhere.
To remedy this issue, preserve the bits when programming the LISN
field in the context control register. Since the LISN will now be
programmed using a read value, assert that the initial state of the
LISN field is as described in SISLite (0).
Signed-off-by: Matthew R. Ochs <redacted>
Signed-off-by: Uma Krishnan <redacted>
---
drivers/scsi/cxlflash/main.c | 5 ++++-
drivers/scsi/cxlflash/sislite.h | 1 +
2 files changed, 5 insertions(+), 1 deletion(-)
@@ -284,6 +284,7 @@ struct sisl_host_map {__be64cmd_room;__be64ctx_ctrl;/* least significant byte or b56:63 is LISN# */#define SISL_CTX_CTRL_UNMAP_SECTOR 0x8000000000000000ULL /* b0 */+#define SISL_CTX_CTRL_LISN_MASK (0xFFULL)__be64mbox_w;/* restricted use */__be64sq_start;/* Submission Queue (R/W): write sequence and */__be64sq_end;/* inclusion semantics are the same as RRQ */
From: Uma Krishnan <hidden> Date: 2018-03-26 16:30:37
Checkpatch throws a warning when the argument identifier names are not
included in the function definitions.
To avoid these warnings, argument identifiers are added in the existing
function definitions.
Signed-off-by: Uma Krishnan <redacted>
Acked-by: Matthew R. Ochs <redacted>
---
drivers/scsi/cxlflash/backend.h | 47 ++++++++++++++++++++++-------------------
drivers/scsi/cxlflash/common.h | 4 ++--
2 files changed, 27 insertions(+), 24 deletions(-)
From: Uma Krishnan <hidden> Date: 2018-03-26 16:30:51
Add initial infrastructure to support a new cxlflash transport, OCXL.
Claim a dependency on OCXL and add a new file, ocxl_hw.c, which will host
the backend routines that are specific to OCXL.
Signed-off-by: Uma Krishnan <redacted>
Acked-by: Matthew R. Ochs <redacted>
Reviewed-by: Andrew Donnellan <redacted>
---
drivers/scsi/cxlflash/Kconfig | 2 +-
drivers/scsi/cxlflash/Makefile | 2 +-
drivers/scsi/cxlflash/backend.h | 1 +
drivers/scsi/cxlflash/ocxl_hw.c | 22 ++++++++++++++++++++++
4 files changed, 25 insertions(+), 2 deletions(-)
create mode 100644 drivers/scsi/cxlflash/ocxl_hw.c
@@ -4,7 +4,7 @@configCXLFLASHtristate"Support for IBM CAPI Flash"-depends onPCI&&SCSI&&CXL&&EEH+depends onPCI&&SCSI&&CXL&&OCXL&&EEHselectIRQ_POLLdefaultmhelp
From: Uma Krishnan <hidden> Date: 2018-03-26 16:31:01
When an adapter is initialized, transport specific configuration and MMIO
mapping details need to be saved. For CXL, this data is managed by the
underlying kernel module. To maintain a separation between the cxlflash
core and underlying transports, introduce a new structure to store data
specific to the OCXL AFU.
Initially only the pointers to underlying PCI and generic devices are
added to this new structure - it will be expanded further in future
commits. Services to create and destroy this hardware AFU are added and
integrated in the probe and exit paths of the driver.
Signed-off-by: Uma Krishnan <redacted>
Acked-by: Matthew R. Ochs <redacted>
Reviewed-by: Andrew Donnellan <redacted>
---
drivers/scsi/cxlflash/backend.h | 1 +
drivers/scsi/cxlflash/cxl_hw.c | 6 ++++++
drivers/scsi/cxlflash/main.c | 9 +++++++--
drivers/scsi/cxlflash/ocxl_hw.c | 40 ++++++++++++++++++++++++++++++++++++++++
drivers/scsi/cxlflash/ocxl_hw.h | 19 +++++++++++++++++++
5 files changed, 73 insertions(+), 2 deletions(-)
create mode 100644 drivers/scsi/cxlflash/ocxl_hw.h
From: Uma Krishnan <hidden> Date: 2018-03-26 16:31:09
Per the OCXL specification, the underlying host can have multiple AFUs
per function with each function supporting its own configuration. The host
function configuration is read on the initialization path to evaluate the
number of functions present and identify the features and configuration of
the functions present. This data is cached for use in later configuration
steps. Note that for the OCXL hardware supported by the cxlflash driver,
only one AFU per function is expected.
Signed-off-by: Uma Krishnan <redacted>
Acked-by: Matthew R. Ochs <redacted>
Reviewed-by: Andrew Donnellan <redacted>
Reviewed-by: Frederic Barrat <redacted>
---
drivers/scsi/cxlflash/ocxl_hw.c | 44 +++++++++++++++++++++++++++++++++++++++++
drivers/scsi/cxlflash/ocxl_hw.h | 4 ++++
2 files changed, 48 insertions(+)
@@ -32,6 +32,38 @@ static void ocxlflash_destroy_afu(void *afu_cookie)}/**+*ocxlflash_config_fn()-configurethehostfunction+*@pdev:PCIdeviceassociatedwiththehost.+*@afu:AFUassociatedwiththehost.+*+*Return:0onsuccess,-errnoonfailure+*/+staticintocxlflash_config_fn(structpci_dev*pdev,structocxl_hw_afu*afu)+{+structocxl_fn_config*fcfg=&afu->fcfg;+structdevice*dev=&pdev->dev;+intrc=0;++/* Read DVSEC config of the function */+rc=ocxl_config_read_function(pdev,fcfg);+if(unlikely(rc)){+dev_err(dev,"%s: ocxl_config_read_function failed rc=%d\n",+__func__,rc);+gotoout;+}++/* Check if function has AFUs defined, only 1 per function supported */+if(fcfg->max_afu_index>=0){+afu->is_present=true;+if(fcfg->max_afu_index!=0)+dev_warn(dev,"%s: Unexpected AFU index value %d\n",+__func__,fcfg->max_afu_index);+}+out:+returnrc;+}++/***ocxlflash_create_afu()-createtheAFUforOCXL*@pdev:PCIdeviceassociatedwiththehost.*
@@ -16,4 +16,8 @@structocxl_hw_afu{structpci_dev*pdev;/* PCI device */structdevice*dev;/* Generic device */++structocxl_fn_configfcfg;/* DVSEC config of the function */++boolis_present;/* Function has AFUs defined */};
From: Uma Krishnan <hidden> Date: 2018-03-26 16:31:21
The OCXL specification supports distributing acTags amongst different
AFUs and functions on the link. The platform-specific acTag range for the
link is obtained using the OCXL provider services and then assigned to the
host function based on implementation.
Signed-off-by: Uma Krishnan <redacted>
Acked-by: Matthew R. Ochs <redacted>
Reviewed-by: Andrew Donnellan <redacted>
Reviewed-by: Frederic Barrat <redacted>
---
drivers/scsi/cxlflash/ocxl_hw.c | 15 +++++++++++++++
drivers/scsi/cxlflash/ocxl_hw.h | 3 +++
2 files changed, 18 insertions(+)
@@ -42,6 +42,7 @@ static int ocxlflash_config_fn(struct pci_dev *pdev, struct ocxl_hw_afu *afu){structocxl_fn_config*fcfg=&afu->fcfg;structdevice*dev=&pdev->dev;+u16base,enabled,supported;intrc=0;/* Read DVSEC config of the function */
@@ -59,6 +60,20 @@ static int ocxlflash_config_fn(struct pci_dev *pdev, struct ocxl_hw_afu *afu)dev_warn(dev,"%s: Unexpected AFU index value %d\n",__func__,fcfg->max_afu_index);}++rc=ocxl_config_get_actag_info(pdev,&base,&enabled,&supported);+if(unlikely(rc)){+dev_err(dev,"%s: ocxl_config_get_actag_info failed rc=%d\n",+__func__,rc);+gotoout;+}++afu->fn_actag_base=base;+afu->fn_actag_enabled=enabled;++ocxl_config_set_actag(pdev,fcfg->dvsec_function_pos,base,enabled);+dev_dbg(dev,"%s: Function acTag range base=%u enabled=%u\n",+__func__,base,enabled);out:returnrc;}
@@ -19,5 +19,8 @@ struct ocxl_hw_afu {structocxl_fn_configfcfg;/* DVSEC config of the function */+intfn_actag_base;/* Function acTag base */+intfn_actag_enabled;/* Function acTag number enabled */+boolis_present;/* Function has AFUs defined */};
From: Uma Krishnan <hidden> Date: 2018-03-26 16:31:29
The host AFU configuration is read on the initialization path to identify
the features and configuration of the AFU. This data is cached for use in
later configuration steps.
Signed-off-by: Uma Krishnan <redacted>
Acked-by: Matthew R. Ochs <redacted>
Reviewed-by: Andrew Donnellan <redacted>
Reviewed-by: Frederic Barrat <redacted>
---
drivers/scsi/cxlflash/ocxl_hw.c | 38 ++++++++++++++++++++++++++++++++++++++
drivers/scsi/cxlflash/ocxl_hw.h | 1 +
2 files changed, 39 insertions(+)
@@ -79,6 +79,37 @@ static int ocxlflash_config_fn(struct pci_dev *pdev, struct ocxl_hw_afu *afu)}/**+*ocxlflash_config_afu()-configurethehostAFU+*@pdev:PCIdeviceassociatedwiththehost.+*@afu:AFUassociatedwiththehost.+*+*Mustbecalled_after_hostfunctionconfiguration.+*+*Return:0onsuccess,-errnoonfailure+*/+staticintocxlflash_config_afu(structpci_dev*pdev,structocxl_hw_afu*afu)+{+structocxl_afu_config*acfg=&afu->acfg;+structocxl_fn_config*fcfg=&afu->fcfg;+structdevice*dev=&pdev->dev;+intrc=0;++/* This HW AFU function does not have any AFUs defined */+if(!afu->is_present)+gotoout;++/* Read AFU config at index 0 */+rc=ocxl_config_read_afu(pdev,fcfg,acfg,0);+if(unlikely(rc)){+dev_err(dev,"%s: ocxl_config_read_afu failed rc=%d\n",+__func__,rc);+gotoout;+}+out:+returnrc;+}++/***ocxlflash_create_afu()-createtheAFUforOCXL*@pdev:PCIdeviceassociatedwiththehost.*
@@ -18,6 +18,7 @@ struct ocxl_hw_afu {structdevice*dev;/* Generic device */structocxl_fn_configfcfg;/* DVSEC config of the function */+structocxl_afu_configacfg;/* AFU configuration data */intfn_actag_base;/* Function acTag base */intfn_actag_enabled;/* Function acTag number enabled */
From: Uma Krishnan <hidden> Date: 2018-03-26 16:31:36
The OCXL specification supports distributing acTags amongst different
AFUs and functions on the link. As cxlflash devices are expected to only
support a single AFU per function, the entire range that was assigned to
the function is also assigned to the AFU.
Signed-off-by: Uma Krishnan <redacted>
Acked-by: Matthew R. Ochs <redacted>
Reviewed-by: Andrew Donnellan <redacted>
Reviewed-by: Frederic Barrat <redacted>
---
drivers/scsi/cxlflash/ocxl_hw.c | 13 +++++++++++++
drivers/scsi/cxlflash/ocxl_hw.h | 2 ++
2 files changed, 15 insertions(+)
@@ -92,6 +92,9 @@ static int ocxlflash_config_afu(struct pci_dev *pdev, struct ocxl_hw_afu *afu)structocxl_afu_config*acfg=&afu->acfg;structocxl_fn_config*fcfg=&afu->fcfg;structdevice*dev=&pdev->dev;+intcount;+intbase;+intpos;intrc=0;/* This HW AFU function does not have any AFUs defined */
@@ -105,6 +108,16 @@ static int ocxlflash_config_afu(struct pci_dev *pdev, struct ocxl_hw_afu *afu)__func__,rc);gotoout;}++/* Only one AFU per function is supported, so actag_base is same */+base=afu->fn_actag_base;+count=min_t(int,acfg->actag_supported,afu->fn_actag_enabled);+pos=acfg->dvsec_afu_control_pos;++ocxl_config_set_afu_actag(pdev,pos,base,count);+dev_dbg(dev,"%s: acTag base=%d enabled=%d\n",__func__,base,count);+afu->afu_actag_base=base;+afu->afu_actag_enabled=count;out:returnrc;}
@@ -22,6 +22,8 @@ struct ocxl_hw_afu {intfn_actag_base;/* Function acTag base */intfn_actag_enabled;/* Function acTag number enabled */+intafu_actag_base;/* AFU acTag base */+intafu_actag_enabled;/* AFU acTag number enabled */boolis_present;/* Function has AFUs defined */};
From: Uma Krishnan <hidden> Date: 2018-03-26 16:31:44
Per the OCXL specification, the maximum PASID supported by the AFU is
indicated by a field within the configuration space. Similar to acTags,
implementations can choose to use any sub-range of PASID within their
assigned range. For cxlflash, the entire range is used.
Signed-off-by: Uma Krishnan <redacted>
Acked-by: Matthew R. Ochs <redacted>
Reviewed-by: Andrew Donnellan <redacted>
Reviewed-by: Frederic Barrat <redacted>
---
drivers/scsi/cxlflash/ocxl_hw.c | 3 +++
drivers/scsi/cxlflash/ocxl_hw.h | 1 +
2 files changed, 4 insertions(+)
@@ -25,5 +25,6 @@ struct ocxl_hw_afu {intafu_actag_base;/* AFU acTag base */intafu_actag_enabled;/* AFU acTag number enabled */+intmax_pasid;/* Maximum number of contexts */boolis_present;/* Function has AFUs defined */};
From: Uma Krishnan <hidden> Date: 2018-03-26 16:31:53
Add support to create and release the adapter contexts for OCXL and
provide means to specify certain contexts as a master.
The existing cxlflash core has a design requirement that each host will
have a single host context available by default. To satisfy this
requirement, one host adapter context is created when the hardware AFU is
initialized. This is returned by the get_context() fop.
Signed-off-by: Uma Krishnan <redacted>
Acked-by: Matthew R. Ochs <redacted>
Reviewed-by: Frederic Barrat <redacted>
---
drivers/scsi/cxlflash/ocxl_hw.c | 90 +++++++++++++++++++++++++++++++++++++++++
drivers/scsi/cxlflash/ocxl_hw.h | 6 +++
2 files changed, 96 insertions(+)
@@ -28,3 +29,8 @@ struct ocxl_hw_afu {intmax_pasid;/* Maximum number of contexts */boolis_present;/* Function has AFUs defined */};++structocxlflash_context{+structocxl_hw_afu*hw_afu;/* HW AFU back pointer */+boolmaster;/* Whether this is a master context */+};
From: Uma Krishnan <hidden> Date: 2018-03-26 16:32:00
A range of PASIDs are used as identifiers for the adapter contexts. These
contexts may be destroyed and created randomly. Use an IDR to keep track
of contexts that are in use and assign a unique identifier to new ones.
Signed-off-by: Uma Krishnan <redacted>
Acked-by: Matthew R. Ochs <redacted>
---
drivers/scsi/cxlflash/ocxl_hw.c | 21 +++++++++++++++++++--
drivers/scsi/cxlflash/ocxl_hw.h | 2 ++
2 files changed, 21 insertions(+), 2 deletions(-)
@@ -26,6 +26,7 @@ struct ocxl_hw_afu {intafu_actag_base;/* AFU acTag base */intafu_actag_enabled;/* AFU acTag number enabled */+structidridr;/* IDR to manage contexts */intmax_pasid;/* Maximum number of contexts */boolis_present;/* Function has AFUs defined */};
@@ -33,4 +34,5 @@ struct ocxl_hw_afu {structocxlflash_context{structocxl_hw_afu*hw_afu;/* HW AFU back pointer */boolmaster;/* Whether this is a master context */+intpe;/* Process element */};
From: Uma Krishnan <hidden> Date: 2018-03-26 16:32:09
Allocate a file descriptor for an adapter context when requested. In order
to allocate inodes for the file descriptors, a pseudo filesystem is created
and used.
Signed-off-by: Uma Krishnan <redacted>
Acked-by: Matthew R. Ochs <redacted>
---
drivers/scsi/cxlflash/ocxl_hw.c | 200 ++++++++++++++++++++++++++++++++++++++++
drivers/scsi/cxlflash/ocxl_hw.h | 1 +
2 files changed, 201 insertions(+)
@@ -100,6 +232,7 @@ static int ocxlflash_release_context(void *ctx_cookie)gotoout;idr_remove(&ctx->hw_afu->idr,ctx->pe);+ocxlflash_release_mapping(ctx);kfree(ctx);out:returnrc;
@@ -270,6 +403,72 @@ static void *ocxlflash_create_afu(struct pci_dev *pdev)gotoout;}+staticconststructfile_operationsocxl_afu_fops={+.owner=THIS_MODULE,+};++/**+*ocxlflash_get_fd()-getfiledescriptorforanadaptercontext+*@ctx_cookie:Adaptercontext.+*@fops:Fileoperationstobeassociated.+*@fd:Filedescriptortobereturnedback.+*+*Return:pointertothefileonsuccess,ERR_PTRonfailure+*/+staticstructfile*ocxlflash_get_fd(void*ctx_cookie,+structfile_operations*fops,int*fd)+{+structocxlflash_context*ctx=ctx_cookie;+structdevice*dev=ctx->hw_afu->dev;+structfile*file;+intflags,fdtmp;+intrc=0;+char*name=NULL;++/* Only allow one fd per context */+if(ctx->mapping){+dev_err(dev,"%s: Context is already mapped to an fd\n",+__func__);+rc=-EEXIST;+gotoerr1;+}++flags=O_RDWR|O_CLOEXEC;++/* This code is similar to anon_inode_getfd() */+rc=get_unused_fd_flags(flags);+if(unlikely(rc<0)){+dev_err(dev,"%s: get_unused_fd_flags failed rc=%d\n",+__func__,rc);+gotoerr1;+}+fdtmp=rc;++/* Use default ops if there is no fops */+if(!fops)+fops=(structfile_operations*)&ocxl_afu_fops;++name=kasprintf(GFP_KERNEL,"ocxlflash:%d",ctx->pe);+file=ocxlflash_getfile(dev,name,fops,ctx,flags);+kfree(name);+if(IS_ERR(file)){+rc=PTR_ERR(file);+dev_err(dev,"%s: ocxlflash_getfile failed rc=%d\n",+__func__,rc);+gotoerr2;+}++ctx->mapping=file->f_mapping;+*fd=fdtmp;+out:+returnfile;+err2:+put_unused_fd(fdtmp);+err1:+file=ERR_PTR(rc);+gotoout;+}+/* Backend ops to ocxlflash services */conststructcxlflash_backend_opscxlflash_ocxl_ops={.module=THIS_MODULE,
@@ -33,6 +33,7 @@ struct ocxl_hw_afu {structocxlflash_context{structocxl_hw_afu*hw_afu;/* HW AFU back pointer */+structaddress_space*mapping;/* Mapping for pseudo filesystem */boolmaster;/* Whether this is a master context */intpe;/* Process element */};
From: Uma Krishnan <hidden> Date: 2018-03-26 16:32:20
Provide means to obtain the process element of an adapter context as well
as locate an adapter context by file.
Signed-off-by: Uma Krishnan <redacted>
Acked-by: Matthew R. Ochs <redacted>
---
drivers/scsi/cxlflash/ocxl_hw.c | 26 ++++++++++++++++++++++++++
1 file changed, 26 insertions(+)
From: Uma Krishnan <hidden> Date: 2018-03-26 16:32:29
On a PERST, the AFU image can be reloaded or left intact. Provide means to
set this image reload policy.
Signed-off-by: Uma Krishnan <redacted>
Acked-by: Matthew R. Ochs <redacted>
---
drivers/scsi/cxlflash/ocxl_hw.c | 13 +++++++++++++
drivers/scsi/cxlflash/ocxl_hw.h | 1 +
2 files changed, 14 insertions(+)
From: Uma Krishnan <hidden> Date: 2018-03-26 16:32:37
When the AFU is configured, the global and per process MMIO regions
are presented by the configuration space. Save these regions and
map the global MMIO region that is used to access all of the control
and provisioning data in the AFU.
Signed-off-by: Uma Krishnan <redacted>
Acked-by: Matthew R. Ochs <redacted>
Reviewed-by: Frederic Barrat <redacted>
---
drivers/scsi/cxlflash/ocxl_hw.c | 74 ++++++++++++++++++++++++++++++++++++++++-
drivers/scsi/cxlflash/ocxl_hw.h | 4 +++
2 files changed, 77 insertions(+), 1 deletion(-)
@@ -27,6 +27,10 @@ struct ocxl_hw_afu {intafu_actag_base;/* AFU acTag base */intafu_actag_enabled;/* AFU acTag number enabled */+phys_addr_tppmmio_phys;/* Per process MMIO space */+phys_addr_tgmmio_phys;/* Global AFU MMIO space */+void__iomem*gmmio_virt;/* Global MMIO map */+structidridr;/* IDR to manage contexts */intmax_pasid;/* Maximum number of contexts */boolis_present;/* Function has AFUs defined */
From: Uma Krishnan <hidden> Date: 2018-03-26 16:32:48
Once the adapter context is created, it needs to be started by assigning
the MMIO space for the context and by enabling the process element in the
link. This commit adds the skeleton for starting the context and assigns
the context specific MMIO space. Master contexts have access to the global
MMIO space while the rest have access to the context specific space.
Signed-off-by: Uma Krishnan <redacted>
Acked-by: Matthew R. Ochs <redacted>
---
drivers/scsi/cxlflash/ocxl_hw.c | 39 +++++++++++++++++++++++++++++++++++++++
drivers/scsi/cxlflash/ocxl_hw.h | 3 +++
2 files changed, 42 insertions(+)
@@ -41,4 +41,7 @@ struct ocxlflash_context {structaddress_space*mapping;/* Mapping for pseudo filesystem */boolmaster;/* Whether this is a master context */intpe;/* Process element */++phys_addr_tpsn_phys;/* Process mapping */+u64psn_size;/* Process mapping size */};
From: Uma Krishnan <hidden> Date: 2018-03-26 16:32:56
Once the context is started, the assigned MMIO space can be mapped
and unmapped. Provide means to map and unmap the context MMIO space.
Signed-off-by: Uma Krishnan <redacted>
Acked-by: Matthew R. Ochs <redacted>
---
drivers/scsi/cxlflash/ocxl_hw.c | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
From: Uma Krishnan <hidden> Date: 2018-03-26 16:33:05
The AFU should be enabled following a successful configuration and
disabled near the end of the cleanup path.
Signed-off-by: Uma Krishnan <redacted>
Acked-by: Matthew R. Ochs <redacted>
Reviewed-by: Frederic Barrat <redacted>
---
drivers/scsi/cxlflash/ocxl_hw.c | 9 +++++++++
1 file changed, 9 insertions(+)
From: Uma Krishnan <hidden> Date: 2018-03-26 16:33:14
Use the PCI VPD services to support reading the VPD data of the
underlying adapter.
Signed-off-by: Uma Krishnan <redacted>
Acked-by: Matthew R. Ochs <redacted>
---
drivers/scsi/cxlflash/ocxl_hw.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)
From: Uma Krishnan <hidden> Date: 2018-03-26 16:33:21
After reading and modifying the function configuration, setup the OCXL
link using the OCXL provider services. The link is released when the
adapter is unconfigured.
Signed-off-by: Uma Krishnan <redacted>
Acked-by: Matthew R. Ochs <redacted>
Reviewed-by: Frederic Barrat <redacted>
---
drivers/scsi/cxlflash/ocxl_hw.c | 25 ++++++++++++++++++++++---
drivers/scsi/cxlflash/ocxl_hw.h | 1 +
2 files changed, 23 insertions(+), 3 deletions(-)
@@ -31,6 +31,7 @@ struct ocxl_hw_afu {phys_addr_tgmmio_phys;/* Global AFU MMIO space */void__iomem*gmmio_virt;/* Global MMIO map */+void*link_token;/* Link token for the SPA */structidridr;/* IDR to manage contexts */intmax_pasid;/* Maximum number of contexts */boolis_present;/* Function has AFUs defined */
From: Uma Krishnan <hidden> Date: 2018-03-26 16:33:28
The first function of the link needs to configure the transaction layer
between the host and device. This is accomplished by a call to the OCXL
provider services.
Signed-off-by: Uma Krishnan <redacted>
Acked-by: Matthew R. Ochs <redacted>
---
drivers/scsi/cxlflash/ocxl_hw.c | 10 ++++++++++
1 file changed, 10 insertions(+)
From: Uma Krishnan <hidden> Date: 2018-03-26 16:33:35
As part of the context lifecycle, the associated process element within
the Shared Process Area (SPA) of the link must be updated. Each process
is defined by various parameters (pid, tid, PASID mm) that are stored in
the SPA upon starting a context and invalidated when a context is stopped.
Use the OCXL provider services to configure the SPA with the appropriate
data that is unique to the process when starting a context. Initially only
kernel contexts are supported and therefore these process values are not
applicable. Note that the OCXL service used has an optional callback for
translation fault error notification. While not used here, it will be
expanded in a future commit.
Also add a service to stop a context by terminating the corresponding
PASID and remove the process element from the SPA.
Signed-off-by: Uma Krishnan <redacted>
Acked-by: Matthew R. Ochs <redacted>
---
drivers/scsi/cxlflash/ocxl_hw.c | 52 +++++++++++++++++++++++++++++++++++++++--
1 file changed, 50 insertions(+), 2 deletions(-)
@@ -189,7 +189,7 @@ static int ocxlflash_process_element(void *ctx_cookie)*start_context()-localroutinetostartacontext*@ctx:Adaptercontexttobestarted.*-*AssignthecontextspecificMMIOspace.+*AssignthecontextspecificMMIOspace,addandenablethePE.**Return:0onsuccess,-errnoonfailure*/
@@ -197,7 +197,10 @@ static int start_context(struct ocxlflash_context *ctx){structocxl_hw_afu*afu=ctx->hw_afu;structocxl_afu_config*acfg=&afu->acfg;+void*link_token=afu->link_token;+structdevice*dev=afu->dev;boolmaster=ctx->master;+intrc=0;if(master){ctx->psn_size=acfg->global_mmio_size;
@@ -207,7 +210,16 @@ static int start_context(struct ocxlflash_context *ctx)ctx->psn_phys=afu->ppmmio_phys+(ctx->pe*ctx->psn_size);}-return0;++/* pid, tid, amr and mm are zeroes/NULL for a kernel context */+rc=ocxl_link_add_pe(link_token,ctx->pe,0,0,0,NULL,NULL,NULL);+if(unlikely(rc)){+dev_err(dev,"%s: ocxl_link_add_pe failed rc=%d\n",+__func__,rc);+gotoout;+}+out:+returnrc;}/**
@@ -224,6 +236,41 @@ static int ocxlflash_start_context(void *ctx_cookie)}/**+*ocxlflash_stop_context()-stopacontext+*@ctx_cookie:Adaptercontexttobestopped.+*+*Return:0onsuccess,-errnoonfailure+*/+staticintocxlflash_stop_context(void*ctx_cookie)+{+structocxlflash_context*ctx=ctx_cookie;+structocxl_hw_afu*afu=ctx->hw_afu;+structocxl_afu_config*acfg=&afu->acfg;+structpci_dev*pdev=afu->pdev;+structdevice*dev=afu->dev;+intrc;++rc=ocxl_config_terminate_pasid(pdev,acfg->dvsec_afu_control_pos,+ctx->pe);+if(unlikely(rc)){+dev_err(dev,"%s: ocxl_config_terminate_pasid failed rc=%d\n",+__func__,rc);+/* If EBUSY, PE could be referenced in future by the AFU */+if(rc==-EBUSY)+gotoout;+}++rc=ocxl_link_remove_pe(afu->link_token,ctx->pe);+if(unlikely(rc)){+dev_err(dev,"%s: ocxl_link_remove_pe failed rc=%d\n",+__func__,rc);+gotoout;+}+out:+returnrc;+}++/***ocxlflash_set_master()-setsthecontextasmaster*@ctx_cookie:Adaptercontexttosetasmaster.*/
From: Uma Krishnan <hidden> Date: 2018-03-26 16:33:41
Add support to allocate and free AFU interrupts using the OCXL provider
services. The trigger page returned upon successful allocation will be
mapped and exposed to the cxlflash core in a future commit.
Signed-off-by: Uma Krishnan <redacted>
Acked-by: Matthew R. Ochs <redacted>
---
drivers/scsi/cxlflash/ocxl_hw.c | 104 ++++++++++++++++++++++++++++++++++++++++
drivers/scsi/cxlflash/ocxl_hw.h | 10 ++++
2 files changed, 114 insertions(+)
@@ -12,6 +12,13 @@*2oftheLicense,or(atyouroption)anylaterversion.*/+#define OCXL_MAX_IRQS 4 /* Max interrupts per process */++structocxlflash_irqs{+inthwirq;+u64ptrig;+};+/* OCXL hardware AFU associated with the host */structocxl_hw_afu{structocxlflash_context*ocxl_ctx;/* Host context */
@@ -45,4 +52,7 @@ struct ocxlflash_context {phys_addr_tpsn_phys;/* Process mapping */u64psn_size;/* Process mapping size */++structocxlflash_irqs*irqs;/* Pointer to array of structures */+intnum_irqs;/* Number of interrupts */};
From: Uma Krishnan <hidden> Date: 2018-03-26 16:33:48
Add support to map and unmap the irq space and manage irq registrations
with the kernel for each allocated AFU interrupt. Also support mapping
the physical trigger page to obtain an effective address that will be
provided to the cxlflash core in a future commit.
Signed-off-by: Uma Krishnan <redacted>
Acked-by: Matthew R. Ochs <redacted>
---
drivers/scsi/cxlflash/ocxl_hw.c | 120 ++++++++++++++++++++++++++++++++++++++++
drivers/scsi/cxlflash/ocxl_hw.h | 2 +
2 files changed, 122 insertions(+)
From: Uma Krishnan <hidden> Date: 2018-03-26 16:33:55
User contexts request interrupts and are started using the "start work"
interface. Populate the start_work() fop to allocate and map interrupts
before starting the user context. As part of starting the context, update
the user process identification logic to properly derive the data required
by the SPA. Also, introduce a skeleton interrupt handler using a bitmap,
flag, and spinlock to track interrupts. This handler will be expanded in
future commits.
Signed-off-by: Uma Krishnan <redacted>
Acked-by: Matthew R. Ochs <redacted>
---
drivers/scsi/cxlflash/ocxl_hw.c | 99 ++++++++++++++++++++++++++++++++++++++++-
drivers/scsi/cxlflash/ocxl_hw.h | 3 ++
2 files changed, 100 insertions(+), 2 deletions(-)
@@ -318,7 +318,9 @@ static int start_context(struct ocxlflash_context *ctx)void*link_token=afu->link_token;structdevice*dev=afu->dev;boolmaster=ctx->master;+structmm_struct*mm;intrc=0;+u32pid;if(master){ctx->psn_size=acfg->global_mmio_size;
@@ -328,9 +330,16 @@ static int start_context(struct ocxlflash_context *ctx)ctx->psn_phys=afu->ppmmio_phys+(ctx->pe*ctx->psn_size);}+/* pid and mm not set for master contexts */+if(master){+pid=0;+mm=NULL;+}else{+pid=current->mm->context.id;+mm=current->mm;+}-/* pid, tid, amr and mm are zeroes/NULL for a kernel context */-rc=ocxl_link_add_pe(link_token,ctx->pe,0,0,0,NULL,NULL,NULL);+rc=ocxl_link_add_pe(link_token,ctx->pe,pid,0,0,mm,NULL,NULL);if(unlikely(rc)){dev_err(dev,"%s: ocxl_link_add_pe failed rc=%d\n",__func__,rc);
@@ -55,6 +55,9 @@ struct ocxlflash_context {phys_addr_tpsn_phys;/* Process mapping */u64psn_size;/* Process mapping size */+spinlock_tslock;/* Protects irq/fault/event updates */structocxlflash_irqs*irqs;/* Pointer to array of structures */intnum_irqs;/* Number of interrupts */+boolpending_irq;/* Pending interrupt on the context */+ulongirq_bitmap;/* Bits indicating pending irq num */};
From: Uma Krishnan <hidden> Date: 2018-03-26 16:34:03
The cxlflash userspace API requires that users be able to poll the adapter
context for any pending events or interrupts from the AFU. Support polling
on various events by implementing the AFU poll fop using a waitqueue.
Signed-off-by: Uma Krishnan <redacted>
Acked-by: Matthew R. Ochs <redacted>
---
drivers/scsi/cxlflash/ocxl_hw.c | 57 +++++++++++++++++++++++++++++++++++++++--
drivers/scsi/cxlflash/ocxl_hw.h | 2 ++
2 files changed, 57 insertions(+), 2 deletions(-)
@@ -892,10 +894,57 @@ static void *ocxlflash_create_afu(struct pci_dev *pdev)gotoout;}+/**+*ctx_event_pending()-checkforanyeventpendingonthecontext+*@ctx:Contexttobechecked.+*+*Return:trueifthereisaneventpending,falseifnonepending+*/+staticinlineboolctx_event_pending(structocxlflash_context*ctx)+{+if(ctx->pending_irq)+returntrue;++returnfalse;+}++/**+*afu_poll()-polltheAFUforeventsonthecontext+*@file:Fileassociatedwiththeadaptercontext.+*@poll:Pollstructurefromtheuser.+*+*Return:pollmask+*/+staticunsignedintafu_poll(structfile*file,structpoll_table_struct*poll)+{+structocxlflash_context*ctx=file->private_data;+structdevice*dev=ctx->hw_afu->dev;+ulonglock_flags;+intmask=0;++poll_wait(file,&ctx->wq,poll);++spin_lock_irqsave(&ctx->slock,lock_flags);+if(ctx_event_pending(ctx))+mask|=POLLIN|POLLRDNORM;+else+mask|=POLLERR;+spin_unlock_irqrestore(&ctx->slock,lock_flags);++dev_dbg(dev,"%s: Poll wait completed for pe %i mask %i\n",+__func__,ctx->pe,mask);++returnmask;+}+staticconststructfile_operationsocxl_afu_fops={.owner=THIS_MODULE,+.poll=afu_poll,};+#define PATCH_FOPS(NAME) \+do{if(!fops->NAME)fops->NAME=ocxl_afu_fops.NAME;}while(0)+/***ocxlflash_get_fd()-getfiledescriptorforanadaptercontext*@ctx_cookie:Adaptercontext.
@@ -933,8 +982,10 @@ static struct file *ocxlflash_get_fd(void *ctx_cookie,}fdtmp=rc;-/* Use default ops if there is no fops */-if(!fops)+/* Patch the file ops that are not defined */+if(fops){+PATCH_FOPS(poll);+}else/* Use default ops */fops=(structfile_operations*)&ocxl_afu_fops;name=kasprintf(GFP_KERNEL,"ocxlflash:%d",ctx->pe);
@@ -56,6 +56,8 @@ struct ocxlflash_context {u64psn_size;/* Process mapping size */spinlock_tslock;/* Protects irq/fault/event updates */+wait_queue_head_twq;/* Wait queue for poll and interrupts */+structocxlflash_irqs*irqs;/* Pointer to array of structures */intnum_irqs;/* Number of interrupts */boolpending_irq;/* Pending interrupt on the context */
From: Uma Krishnan <hidden> Date: 2018-03-26 16:34:12
The cxlflash userspace API requires that users be able to read the adapter
context for any pending events or interrupts from the AFU. Support reading
various events by implementing the AFU read fop to copy out event data.
Signed-off-by: Uma Krishnan <redacted>
Acked-by: Matthew R. Ochs <redacted>
---
drivers/scsi/cxlflash/ocxl_hw.c | 94 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 94 insertions(+)
@@ -937,9 +940,99 @@ static unsigned int afu_poll(struct file *file, struct poll_table_struct *poll)returnmask;}+/**+*afu_read()-performareadonthecontextforanyevent+*@file:Fileassociatedwiththeadaptercontext.+*@buf:Buffertoreceivethedata.+*@count:Sizeofbuffer(maximumbytesthatcanberead).+*@off:Offset.+*+*Return:sizeofthedatareadonsuccess,-errnoonfailure+*/+staticssize_tafu_read(structfile*file,char__user*buf,size_tcount,+loff_t*off)+{+structocxlflash_context*ctx=file->private_data;+structdevice*dev=ctx->hw_afu->dev;+structcxl_eventevent;+ulonglock_flags;+ssize_tesize;+ssize_trc;+intbit;+DEFINE_WAIT(event_wait);++if(*off!=0){+dev_err(dev,"%s: Non-zero offset not supported, off=%lld\n",+__func__,*off);+rc=-EINVAL;+gotoout;+}++spin_lock_irqsave(&ctx->slock,lock_flags);++for(;;){+prepare_to_wait(&ctx->wq,&event_wait,TASK_INTERRUPTIBLE);++if(ctx_event_pending(ctx))+break;++if(file->f_flags&O_NONBLOCK){+dev_err(dev,"%s: File cannot be blocked on I/O\n",+__func__);+rc=-EAGAIN;+gotoerr;+}++if(signal_pending(current)){+dev_err(dev,"%s: Signal pending on the process\n",+__func__);+rc=-ERESTARTSYS;+gotoerr;+}++spin_unlock_irqrestore(&ctx->slock,lock_flags);+schedule();+spin_lock_irqsave(&ctx->slock,lock_flags);+}++finish_wait(&ctx->wq,&event_wait);++memset(&event,0,sizeof(event));+event.header.process_element=ctx->pe;+event.header.size=sizeof(structcxl_event_header);+if(ctx->pending_irq){+esize=sizeof(structcxl_event_afu_interrupt);+event.header.size+=esize;+event.header.type=CXL_EVENT_AFU_INTERRUPT;++bit=find_first_bit(&ctx->irq_bitmap,ctx->num_irqs);+clear_bit(bit,&ctx->irq_bitmap);+event.irq.irq=bit+1;+if(bitmap_empty(&ctx->irq_bitmap,ctx->num_irqs))+ctx->pending_irq=false;+}++spin_unlock_irqrestore(&ctx->slock,lock_flags);++if(copy_to_user(buf,&event,event.header.size)){+dev_err(dev,"%s: copy_to_user failed\n",__func__);+rc=-EFAULT;+gotoout;+}++rc=event.header.size;+out:+returnrc;+err:+finish_wait(&ctx->wq,&event_wait);+spin_unlock_irqrestore(&ctx->slock,lock_flags);+gotoout;+}+staticconststructfile_operationsocxl_afu_fops={.owner=THIS_MODULE,.poll=afu_poll,+.read=afu_read,};#define PATCH_FOPS(NAME) \
@@ -985,6 +1078,7 @@ static struct file *ocxlflash_get_fd(void *ctx_cookie,/* Patch the file ops that are not defined */if(fops){PATCH_FOPS(poll);+PATCH_FOPS(read);}else/* Use default ops */fops=(structfile_operations*)&ocxl_afu_fops;
From: Uma Krishnan <hidden> Date: 2018-03-26 16:34:20
The cxlflash userspace API requires that users be able to mmap and release
the adapter context. Support mapping by implementing the AFU mmap fop to
map the context MMIO space and install the corresponding page table entry
upon page fault. Similarly, implement the AFU release fop to terminate and
clean up the context when invoked.
Signed-off-by: Uma Krishnan <redacted>
Acked-by: Matthew R. Ochs <redacted>
---
drivers/scsi/cxlflash/ocxl_hw.c | 72 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 72 insertions(+)
From: Uma Krishnan <hidden> Date: 2018-03-26 16:34:27
The cxlflash core fop API requires a way to invoke the fault and release
handlers of underlying transports using their native file-based APIs. This
provides the core with the ability to insert selectively itself into the
processing stream of these operations for cleanup. Implement these two
fops to map and release when requested.
Signed-off-by: Uma Krishnan <redacted>
Acked-by: Matthew R. Ochs <redacted>
---
drivers/scsi/cxlflash/ocxl_hw.c | 26 ++++++++++++++++++++++++++
1 file changed, 26 insertions(+)
From: Uma Krishnan <hidden> Date: 2018-03-26 16:34:35
OCXL requires that AFUs use an opaque object handle to represent
an AFU interrupt. The specification does not provide a common means
to communicate the object handle to the AFU - each AFU must define
this within the AFU specification. To support this model, the object
handle must be passed back to the core driver as it manages the AFU
specification (SISLite) for cxlflash. Note that for Power systems,
the object handle is the effective address of the trigger page.
Signed-off-by: Uma Krishnan <redacted>
Acked-by: Matthew R. Ochs <redacted>
---
drivers/scsi/cxlflash/backend.h | 1 +
drivers/scsi/cxlflash/cxl_hw.c | 7 +++++++
drivers/scsi/cxlflash/ocxl_hw.c | 18 ++++++++++++++++++
3 files changed, 26 insertions(+)
From: Uma Krishnan <hidden> Date: 2018-03-26 16:34:42
The SISLite specification has been updated for OCXL to support
communicating data to generate AFU interrupts to the AFU. This includes
a new capability bit that is advertised for OCXL AFUs and new registers
to hold the object handle and translation PASID of each interrupt. For
Power, the object handle is the mapped trigger page. Note that because
these mappings are kernel only, the PASID of a kernel context must be
used to satisfy the translation.
Signed-off-by: Uma Krishnan <redacted>
Acked-by: Matthew R. Ochs <redacted>
---
drivers/scsi/cxlflash/common.h | 5 +++++
drivers/scsi/cxlflash/sislite.h | 5 +++++
drivers/scsi/cxlflash/superpipe.c | 14 ++++++++++++++
3 files changed, 24 insertions(+)
@@ -269,6 +269,7 @@ static int afu_attach(struct cxlflash_cfg *cfg, struct ctx_info *ctxi)intrc=0;structhwq*hwq=get_hwq(afu,PRIMARY_HWQ);u64val;+inti;/* Unlock cap and restrict user to read/write cmds in translated mode */readq_be(&ctrl_map->mbox_r);
@@ -282,6 +283,19 @@ static int afu_attach(struct cxlflash_cfg *cfg, struct ctx_info *ctxi)gotoout;}+if(afu_is_ocxl_lisn(afu)){+/* Set up the LISN effective address for each interrupt */+for(i=0;i<ctxi->irqs;i++){+val=cfg->ops->get_irq_objhndl(ctxi->ctx,i);+writeq_be(val,&ctrl_map->lisn_ea[i]);+}++/* Use primary HWQ PASID as identifier for all interrupts */+val=hwq->ctx_hndl;+writeq_be(SISL_LISN_PASID(val,val),&ctrl_map->lisn_pasid[0]);+writeq_be(SISL_LISN_PASID(0UL,val),&ctrl_map->lisn_pasid[1]);+}+/* Set up MMIO registers pointing to the RHT */writeq_be((u64)ctxi->rht_start,&ctrl_map->rht_start);val=SISL_RHT_CNT_ID((u64)MAX_RHT_PER_CONTEXT,(u64)(hwq->ctx_hndl));
From: Uma Krishnan <hidden> Date: 2018-03-26 16:34:48
Similar to user contexts, master contexts also require that the per-context
LISN registers be programmed for certain AFUs. The mapped trigger page is
obtained from underlying transport and registered with AFU for each master
context.
Signed-off-by: Uma Krishnan <redacted>
Acked-by: Matthew R. Ochs <redacted>
---
drivers/scsi/cxlflash/main.c | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
@@ -1756,6 +1756,8 @@ static int init_global(struct cxlflash_cfg *cfg)u64wwpn[MAX_FC_PORTS];/* wwpn of AFU ports */inti=0,num_ports=0;intrc=0;+intj;+void*ctx;u64reg;rc=read_vpd(cfg,&wwpn[0]);
@@ -1816,6 +1818,25 @@ static int init_global(struct cxlflash_cfg *cfg)msleep(100);}+if(afu_is_ocxl_lisn(afu)){+/* Set up the LISN effective address for each master */+for(i=0;i<afu->num_hwqs;i++){+hwq=get_hwq(afu,i);+ctx=hwq->ctx_cookie;++for(j=0;j<hwq->num_irqs;j++){+reg=cfg->ops->get_irq_objhndl(ctx,j);+writeq_be(reg,&hwq->ctrl_map->lisn_ea[j]);+}++reg=hwq->ctx_hndl;+writeq_be(SISL_LISN_PASID(reg,reg),+&hwq->ctrl_map->lisn_pasid[0]);+writeq_be(SISL_LISN_PASID(0UL,reg),+&hwq->ctrl_map->lisn_pasid[1]);+}+}+/* Set up master's own CTX_CAP to allow real mode, host translation *//* tables, afu cmds and read/write GSCSI cmds. *//* First, unlock ctx_cap write by reading mbox */
From: Uma Krishnan <hidden> Date: 2018-03-26 16:34:55
The SISLite specification has been updated to define new synchronous
interrupt status bits. These bits are set by the AFU when a given PASID or
EA is bad and a synchronous interrupt is triggered.
The SISLite header file is updated to support these new bits. Note that
there are also some formatting updates to some of the existing bits to
allow all of the definitions to line up uniformly.
Signed-off-by: Uma Krishnan <redacted>
Acked-by: Matthew R. Ochs <redacted>
---
drivers/scsi/cxlflash/sislite.h | 35 +++++++++++++++++++++--------------
1 file changed, 21 insertions(+), 14 deletions(-)
From: Uma Krishnan <hidden> Date: 2018-03-26 16:35:00
In order to protect the OCXL hardware contexts from getting clobbered,
a simple state machine is added to indicate when a context is in open,
close or start state. The expected states are validated throughout the
code to prevent illegal operations on a context. A mutex is added to
protect writes to the context state field.
Signed-off-by: Uma Krishnan <redacted>
Acked-by: Matthew R. Ochs <redacted>
---
drivers/scsi/cxlflash/ocxl_hw.c | 59 ++++++++++++++++++++++++++++++++++++++---
drivers/scsi/cxlflash/ocxl_hw.h | 8 ++++++
2 files changed, 64 insertions(+), 3 deletions(-)
@@ -46,6 +46,12 @@ struct ocxl_hw_afu {boolis_present;/* Function has AFUs defined */};+enumocxlflash_ctx_state{+CLOSED,+OPENED,+STARTED+};+structocxlflash_context{structocxl_hw_afu*hw_afu;/* HW AFU back pointer */structaddress_space*mapping;/* Mapping for pseudo filesystem */
@@ -57,6 +63,8 @@ struct ocxlflash_context {spinlock_tslock;/* Protects irq/fault/event updates */wait_queue_head_twq;/* Wait queue for poll and interrupts */+structmutexstate_mutex;/* Mutex to update context state */+enumocxlflash_ctx_statestate;/* Context state */structocxlflash_irqs*irqs;/* Pointer to array of structures */intnum_irqs;/* Number of interrupts */
From: Uma Krishnan <hidden> Date: 2018-03-26 16:35:07
While enabling a context on the link, a predefined callback can be
registered with the OCXL provider services to be notified on translation
errors. These errors can in turn be passed back to the user on a read
operation.
Signed-off-by: Uma Krishnan <redacted>
Acked-by: Matthew R. Ochs <redacted>
---
drivers/scsi/cxlflash/ocxl_hw.c | 31 +++++++++++++++++++++++++++++--
drivers/scsi/cxlflash/ocxl_hw.h | 4 ++++
2 files changed, 33 insertions(+), 2 deletions(-)
@@ -70,4 +70,8 @@ struct ocxlflash_context {intnum_irqs;/* Number of interrupts */boolpending_irq;/* Pending interrupt on the context */ulongirq_bitmap;/* Bits indicating pending irq num */++u64fault_addr;/* Address that triggered the fault */+u64fault_dsisr;/* Value of dsisr register at fault */+boolpending_fault;/* Pending translation fault */};
From: Uma Krishnan <hidden> Date: 2018-03-26 16:35:15
The cxlflash core driver resets the AFU when the master contexts are
created in the initialization or recovery paths. Today, the OCXL
provider service to perform this operation is pending implementation.
To avoid a crash due to a missing fop, log an error once and return
success to continue with execution.
Signed-off-by: Uma Krishnan <redacted>
Acked-by: Matthew R. Ochs <redacted>
---
drivers/scsi/cxlflash/ocxl_hw.c | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
@@ -468,6 +468,22 @@ static int ocxlflash_stop_context(void *ctx_cookie)}/**+*ocxlflash_afu_reset()-resettheAFU+*@ctx_cookie:Adaptercontext.+*/+staticintocxlflash_afu_reset(void*ctx_cookie)+{+structocxlflash_context*ctx=ctx_cookie;+structdevice*dev=ctx->hw_afu->dev;++/* Pending implementation from OCXL transport services */+dev_err_once(dev,"%s: afu_reset() fop not supported\n",__func__);++/* Silently return success until it is implemented */+return0;+}++/***ocxlflash_set_master()-setsthecontextasmaster*@ctx_cookie:Adaptercontexttosetasmaster.*/
From: Uma Krishnan <hidden> Date: 2018-03-26 16:35:21
This commit enables the OCXL operations for the OCXL devices.
Signed-off-by: Uma Krishnan <redacted>
Acked-by: Matthew R. Ochs <redacted>
---
drivers/scsi/cxlflash/main.c | 9 +++++++--
drivers/scsi/cxlflash/main.h | 1 +
2 files changed, 8 insertions(+), 2 deletions(-)
From: Uma Krishnan <hidden> Date: 2018-03-26 16:35:27
The following Oops can be encountered if a device removal or system
shutdown is initiated while an EEH recovery is in process:
[c000000ff2f479c0] c008000015256f18 cxlflash_pci_slot_reset+0xa0/0x100
[cxlflash]
[c000000ff2f47a30] c00800000dae22e0 cxl_pci_slot_reset+0x168/0x290 [cxl]
[c000000ff2f47ae0] c00000000003ef1c eeh_report_reset+0xec/0x170
[c000000ff2f47b20] c00000000003d0b8 eeh_pe_dev_traverse+0x98/0x170
[c000000ff2f47bb0] c00000000003f80c eeh_handle_normal_event+0x56c/0x580
[c000000ff2f47c60] c00000000003fba4 eeh_handle_event+0x2a4/0x338
[c000000ff2f47d10] c0000000000400b8 eeh_event_handler+0x1f8/0x200
[c000000ff2f47dc0] c00000000013da48 kthread+0x1a8/0x1b0
[c000000ff2f47e30] c00000000000b528 ret_from_kernel_thread+0x5c/0xb4
The remove handler frees AFU memory while the EEH recovery is in progress,
leading to a race condition. This can result in a crash if the recovery
thread tries to access this memory.
To resolve this issue, the cxlflash remove handler will evaluate the
device state and yield to any active reset or probing threads.
Signed-off-by: Uma Krishnan <redacted>
---
drivers/scsi/cxlflash/main.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
@@ -946,9 +946,9 @@ static void cxlflash_remove(struct pci_dev *pdev)return;}-/* If a Task Management Function is active, wait for it to complete-*beforecontinuingwithremove.-*/+/* Yield to running recovery threads before continuing with remove */+wait_event(cfg->reset_waitq,cfg->state!=STATE_RESET&&+cfg->state!=STATE_PROBING);spin_lock_irqsave(&cfg->tmf_slock,lock_flags);if(cfg->tmf_active)wait_event_interruptible_lock_irq(cfg->tmf_waitq,
From: Uma Krishnan <hidden> Date: 2018-03-26 16:35:34
The following Oops can occur if an internal command sent to the AFU does
not complete within the timeout:
[c000000ff101b810] c008000016020d94 term_mc+0xfc/0x1b0 [cxlflash]
[c000000ff101b8a0] c008000016020fb0 term_afu+0x168/0x280 [cxlflash]
[c000000ff101b930] c0080000160232ec cxlflash_pci_error_detected+0x184/0x230
[cxlflash]
[c000000ff101b9e0] c00800000d95d468 cxl_vphb_error_detected+0x90/0x150[cxl]
[c000000ff101ba20] c00800000d95f27c cxl_pci_error_detected+0xa4/0x240 [cxl]
[c000000ff101bac0] c00000000003eaf8 eeh_report_error+0xd8/0x1b0
[c000000ff101bb20] c00000000003d0b8 eeh_pe_dev_traverse+0x98/0x170
[c000000ff101bbb0] c00000000003f438 eeh_handle_normal_event+0x198/0x580
[c000000ff101bc60] c00000000003fba4 eeh_handle_event+0x2a4/0x338
[c000000ff101bd10] c0000000000400b8 eeh_event_handler+0x1f8/0x200
[c000000ff101bdc0] c00000000013da48 kthread+0x1a8/0x1b0
[c000000ff101be30] c00000000000b528 ret_from_kernel_thread+0x5c/0xb4
When an internal command times out, the command buffer is freed while it
is still in the pending commands list of the context. This corrupts the
list and when the context is cleaned up, a crash is encountered.
To resolve this issue, when an AFU command or TMF command times out, the
command should be deleted from the hardware queue pending command list
before freeing the buffer.
Signed-off-by: Uma Krishnan <redacted>
---
drivers/scsi/cxlflash/main.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
@@ -2329,6 +2338,11 @@ static int send_afu_cmd(struct afu *afu, struct sisl_ioarcb *rcb)case-ETIMEDOUT:rc=afu->context_reset(hwq);if(rc){+/* Delete the command from pending_cmds list */+spin_lock_irqsave(&hwq->hsq_slock,lock_flags);+list_del(&cmd->list);+spin_unlock_irqrestore(&hwq->hsq_slock,lock_flags);+cxlflash_schedule_async_reset(cfg);break;}
From: Uma Krishnan <hidden> Date: 2018-03-26 16:35:42
The following Oops can occur when there is heavy I/O traffic and the host
is reset by a tool such as sg_reset.
[c000200fff3fbc90] c00800001690117c process_cmd_doneq+0x104/0x500
[cxlflash] (unreliable)
[c000200fff3fbd80] c008000016901648 cxlflash_rrq_irq+0xd0/0x150 [cxlflash]
[c000200fff3fbde0] c000000000193130 __handle_irq_event_percpu+0xa0/0x310
[c000200fff3fbea0] c0000000001933d8 handle_irq_event_percpu+0x38/0x90
[c000200fff3fbee0] c000000000193494 handle_irq_event+0x64/0xb0
[c000200fff3fbf10] c000000000198ea0 handle_fasteoi_irq+0xc0/0x230
[c000200fff3fbf40] c00000000019182c generic_handle_irq+0x4c/0x70
[c000200fff3fbf60] c00000000001794c __do_irq+0x7c/0x1c0
[c000200fff3fbf90] c00000000002a390 call_do_irq+0x14/0x24
[c000200e5828fab0] c000000000017b2c do_IRQ+0x9c/0x130
[c000200e5828fb00] c000000000009b04 h_virt_irq_common+0x114/0x120
When a context is reset, the pending commands are flushed and the AFU
is notified. Before the AFU handles this request there could be command
completion interrupts queued to PHB which are yet to be delivered to the
context. In this scenario, a context could receive an interrupt for a
command that has been flushed, leading to a possible crash when the memory
for the flushed command is accessed.
To resolve this problem, a boolean will indicate if the hardware queue is
ready to process interrupts or not. This can be evaluated in the interrupt
handler before proessing an interrupt.
Signed-off-by: Uma Krishnan <redacted>
---
drivers/scsi/cxlflash/common.h | 1 +
drivers/scsi/cxlflash/main.c | 11 +++++++++++
2 files changed, 12 insertions(+)
@@ -1475,6 +1479,12 @@ static irqreturn_t cxlflash_rrq_irq(int irq, void *data)spin_lock_irqsave(&hwq->hrrq_slock,hrrq_flags);+/* Silently drop spurious interrupts when queue is not online */+if(!hwq->hrrq_online){+spin_unlock_irqrestore(&hwq->hrrq_slock,hrrq_flags);+returnIRQ_HANDLED;+}+if(afu_is_irqpoll_enabled(afu)){irq_poll_sched(&hwq->irqpoll);spin_unlock_irqrestore(&hwq->hrrq_slock,hrrq_flags);
@@ -1781,6 +1791,7 @@ static int init_global(struct cxlflash_cfg *cfg)writeq_be((u64)hwq->hrrq_start,&hmap->rrq_start);writeq_be((u64)hwq->hrrq_end,&hmap->rrq_end);+hwq->hrrq_online=true;if(afu_is_sq_cmd_mode(afu)){writeq_be((u64)hwq->hsq_start,&hmap->sq_start);
From: Matthew R. Ochs <hidden> Date: 2018-03-28 14:43:32
On Mon, Mar 26, 2018 at 11:35:27AM -0500, Uma Krishnan wrote:
The following Oops can be encountered if a device removal or system
shutdown is initiated while an EEH recovery is in process:
[c000000ff2f479c0] c008000015256f18 cxlflash_pci_slot_reset+0xa0/0x100
[cxlflash]
[c000000ff2f47a30] c00800000dae22e0 cxl_pci_slot_reset+0x168/0x290 [cxl]
[c000000ff2f47ae0] c00000000003ef1c eeh_report_reset+0xec/0x170
[c000000ff2f47b20] c00000000003d0b8 eeh_pe_dev_traverse+0x98/0x170
[c000000ff2f47bb0] c00000000003f80c eeh_handle_normal_event+0x56c/0x580
[c000000ff2f47c60] c00000000003fba4 eeh_handle_event+0x2a4/0x338
[c000000ff2f47d10] c0000000000400b8 eeh_event_handler+0x1f8/0x200
[c000000ff2f47dc0] c00000000013da48 kthread+0x1a8/0x1b0
[c000000ff2f47e30] c00000000000b528 ret_from_kernel_thread+0x5c/0xb4
The remove handler frees AFU memory while the EEH recovery is in progress,
leading to a race condition. This can result in a crash if the recovery
thread tries to access this memory.
To resolve this issue, the cxlflash remove handler will evaluate the
device state and yield to any active reset or probing threads.
Signed-off-by: Uma Krishnan <redacted>
From: Matthew R. Ochs <hidden> Date: 2018-03-28 14:50:32
On Mon, Mar 26, 2018 at 11:35:34AM -0500, Uma Krishnan wrote:
The following Oops can occur if an internal command sent to the AFU does
not complete within the timeout:
[c000000ff101b810] c008000016020d94 term_mc+0xfc/0x1b0 [cxlflash]
[c000000ff101b8a0] c008000016020fb0 term_afu+0x168/0x280 [cxlflash]
[c000000ff101b930] c0080000160232ec cxlflash_pci_error_detected+0x184/0x230
[cxlflash]
[c000000ff101b9e0] c00800000d95d468 cxl_vphb_error_detected+0x90/0x150[cxl]
[c000000ff101ba20] c00800000d95f27c cxl_pci_error_detected+0xa4/0x240 [cxl]
[c000000ff101bac0] c00000000003eaf8 eeh_report_error+0xd8/0x1b0
[c000000ff101bb20] c00000000003d0b8 eeh_pe_dev_traverse+0x98/0x170
[c000000ff101bbb0] c00000000003f438 eeh_handle_normal_event+0x198/0x580
[c000000ff101bc60] c00000000003fba4 eeh_handle_event+0x2a4/0x338
[c000000ff101bd10] c0000000000400b8 eeh_event_handler+0x1f8/0x200
[c000000ff101bdc0] c00000000013da48 kthread+0x1a8/0x1b0
[c000000ff101be30] c00000000000b528 ret_from_kernel_thread+0x5c/0xb4
When an internal command times out, the command buffer is freed while it
is still in the pending commands list of the context. This corrupts the
list and when the context is cleaned up, a crash is encountered.
To resolve this issue, when an AFU command or TMF command times out, the
command should be deleted from the hardware queue pending command list
before freeing the buffer.
Signed-off-by: Uma Krishnan <redacted>
From: Matthew R. Ochs <hidden> Date: 2018-03-28 15:03:02
On Mon, Mar 26, 2018 at 11:35:42AM -0500, Uma Krishnan wrote:
The following Oops can occur when there is heavy I/O traffic and the host
is reset by a tool such as sg_reset.
[c000200fff3fbc90] c00800001690117c process_cmd_doneq+0x104/0x500
[cxlflash] (unreliable)
[c000200fff3fbd80] c008000016901648 cxlflash_rrq_irq+0xd0/0x150 [cxlflash]
[c000200fff3fbde0] c000000000193130 __handle_irq_event_percpu+0xa0/0x310
[c000200fff3fbea0] c0000000001933d8 handle_irq_event_percpu+0x38/0x90
[c000200fff3fbee0] c000000000193494 handle_irq_event+0x64/0xb0
[c000200fff3fbf10] c000000000198ea0 handle_fasteoi_irq+0xc0/0x230
[c000200fff3fbf40] c00000000019182c generic_handle_irq+0x4c/0x70
[c000200fff3fbf60] c00000000001794c __do_irq+0x7c/0x1c0
[c000200fff3fbf90] c00000000002a390 call_do_irq+0x14/0x24
[c000200e5828fab0] c000000000017b2c do_IRQ+0x9c/0x130
[c000200e5828fb00] c000000000009b04 h_virt_irq_common+0x114/0x120
When a context is reset, the pending commands are flushed and the AFU
is notified. Before the AFU handles this request there could be command
completion interrupts queued to PHB which are yet to be delivered to the
context. In this scenario, a context could receive an interrupt for a
command that has been flushed, leading to a possible crash when the memory
for the flushed command is accessed.
To resolve this problem, a boolean will indicate if the hardware queue is
ready to process interrupts or not. This can be evaluated in the interrupt
handler before proessing an interrupt.
Signed-off-by: Uma Krishnan <redacted>