ACK: [PATCH X/Y SRU] cxl: Flush PSL cache before resetting the adapter

Colin Ian King colin.king at canonical.com
Tue Oct 11 13:27:41 UTC 2016


On 10/10/16 20:29, Tim Gardner wrote:
> From: Frederic Barrat <fbarrat at linux.vnet.ibm.com>
> 
> BugLink: http://bugs.launchpad.net/bugs/1632049
> 
> If the capi link is going down while the PSL owns a dirty cache line,
> any access from the host for that data could lead to an Uncorrectable
> Error.
> 
> So when resetting the capi adapter through sysfs, make sure the PSL
> cache is flushed. It won't help if there are any active Process
> Elements on the card, as the cache would likely get new dirty cache
> lines immediately, but if resetting an idle adapter, it should avoid
> any bad surprises from data left over from terminated Process Elements.
> 
> Signed-off-by: Frederic Barrat <fbarrat at linux.vnet.ibm.com>
> Reviewed-by: Andrew Donnellan <andrew.donnellan at au1.ibm.com>
> Acked-by: Ian Munsie <imunsie at au1.ibm.com>
> Signed-off-by: Michael Ellerman <mpe at ellerman.id.au>
> (cherry picked from commit aaa2245ed836824f21f8e42e0ab63b1637d1cb20)
> Signed-off-by: Tim Gardner <tim.gardner at canonical.com>
> ---
>  drivers/misc/cxl/cxl.h    |  6 +++++-
>  drivers/misc/cxl/native.c | 31 +++++++++++++++++++++++++++++++
>  drivers/misc/cxl/pci.c    |  3 +++
>  3 files changed, 39 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/misc/cxl/cxl.h b/drivers/misc/cxl/cxl.h
> index 9ecb54b..47137de5 100644
> --- a/drivers/misc/cxl/cxl.h
> +++ b/drivers/misc/cxl/cxl.h
> @@ -155,7 +155,10 @@ static const cxl_p2n_reg_t CXL_PSL_WED_An     = {0x0A0};
>  #define CXL_PSL_SPAP_V    0x0000000000000001ULL
>  
>  /****** CXL_PSL_Control ****************************************************/
> -#define CXL_PSL_Control_tb 0x0000000000000001ULL
> +#define CXL_PSL_Control_tb              (0x1ull << (63-63))
> +#define CXL_PSL_Control_Fr              (0x1ull << (63-31))
> +#define CXL_PSL_Control_Fs_MASK         (0x3ull << (63-29))
> +#define CXL_PSL_Control_Fs_Complete     (0x3ull << (63-29))
>  
>  /****** CXL_PSL_DLCNTL *****************************************************/
>  #define CXL_PSL_DLCNTL_D (0x1ull << (63-28))
> @@ -808,6 +811,7 @@ int cxl_register_one_irq(struct cxl *adapter, irq_handler_t handler,
>  int cxl_check_error(struct cxl_afu *afu);
>  int cxl_afu_slbia(struct cxl_afu *afu);
>  int cxl_tlb_slb_invalidate(struct cxl *adapter);
> +int cxl_data_cache_flush(struct cxl *adapter);
>  int cxl_afu_disable(struct cxl_afu *afu);
>  int cxl_psl_purge(struct cxl_afu *afu);
>  
> diff --git a/drivers/misc/cxl/native.c b/drivers/misc/cxl/native.c
> index ecf7557..09e30e2 100644
> --- a/drivers/misc/cxl/native.c
> +++ b/drivers/misc/cxl/native.c
> @@ -269,6 +269,37 @@ int cxl_tlb_slb_invalidate(struct cxl *adapter)
>  	return 0;
>  }
>  
> +int cxl_data_cache_flush(struct cxl *adapter)
> +{
> +	u64 reg;
> +	unsigned long timeout = jiffies + (HZ * CXL_TIMEOUT);
> +
> +	pr_devel("Flushing data cache\n");
> +
> +	reg = cxl_p1_read(adapter, CXL_PSL_Control);
> +	reg |= CXL_PSL_Control_Fr;
> +	cxl_p1_write(adapter, CXL_PSL_Control, reg);
> +
> +	reg = cxl_p1_read(adapter, CXL_PSL_Control);
> +	while ((reg & CXL_PSL_Control_Fs_MASK) != CXL_PSL_Control_Fs_Complete) {
> +		if (time_after_eq(jiffies, timeout)) {
> +			dev_warn(&adapter->dev, "WARNING: cache flush timed out!\n");
> +			return -EBUSY;
> +		}
> +
> +		if (!cxl_ops->link_ok(adapter, NULL)) {
> +			dev_warn(&adapter->dev, "WARNING: link down when flushing cache\n");
> +			return -EIO;
> +		}
> +		cpu_relax();
> +		reg = cxl_p1_read(adapter, CXL_PSL_Control);
> +	}
> +
> +	reg &= ~CXL_PSL_Control_Fr;
> +	cxl_p1_write(adapter, CXL_PSL_Control, reg);
> +	return 0;
> +}
> +
>  static int cxl_write_sstp(struct cxl_afu *afu, u64 sstp0, u64 sstp1)
>  {
>  	int rc;
> diff --git a/drivers/misc/cxl/pci.c b/drivers/misc/cxl/pci.c
> index 4aea07e..94fceaa 100644
> --- a/drivers/misc/cxl/pci.c
> +++ b/drivers/misc/cxl/pci.c
> @@ -956,6 +956,9 @@ int cxl_pci_reset(struct cxl *adapter)
>  
>  	dev_info(&dev->dev, "CXL reset\n");
>  
> +	/* the adapter is about to be reset, so ignore errors */
> +	cxl_data_cache_flush(adapter);
> +
>  	/* pcie_warm_reset requests a fundamental pci reset which includes a
>  	 * PERST assert/deassert.  PERST triggers a loading of the image
>  	 * if "user" or "factory" is selected in sysfs */
> 
Seems reasonable fix and has limit scope to one driver

Acked-by: Colin Ian King <colin.king at canonical.com>





More information about the kernel-team mailing list