[Skiboot] [PATCH 1/7] xscom: Return OPAL_WRONG_STATE on XSCOM ops if CPU is asleep

Alistair Popple alistair at popple.id.au
Thu Mar 17 15:58:08 AEDT 2016


On Tue, 15 Mar 2016 18:33:51 Russell Currey wrote:
> xscom_read and xscom_write return OPAL_SUCCESS if they worked, and
> OPAL_HARDWARE if they didn't.  This doesn't provide information about why
> the operation failed, such as if the CPU happens to be asleep.
> 
> This is specifically useful in error scanning, so if every CPU is being
> scanned for errors, sleeping CPUs likely aren't the cause of failures.
> 
> So, return OPAL_WRONG_STATE in xscom_read and xscom_write if the CPU is
> sleeping.
> 
> Signed-off-by: Russell Currey <ruscur at russell.cc>
> ---
> This will potentially add some new functionality to the kernel.  I'm not
> sure how that might be useful, but I don't think it can be harmful.

I assume the kernel only checks for rc != 0 such that this minor OPAL API 
change doesn't actually result in any behaviour change for current and 
previous kernels?

Reviewed-by: Alistair Popple <alistair at popple.id.au>

> ---
>  doc/opal-api/opal-xscom-read-write-65-66.txt |  5 +++++
>  hw/xscom.c                                   | 29 
+++++++++++++++++-----------
>  2 files changed, 23 insertions(+), 11 deletions(-)
> 
> diff --git a/doc/opal-api/opal-xscom-read-write-65-66.txt b/doc/opal-
api/opal-xscom-read-write-65-66.txt
> index 92916df..4ed0134 100644
> --- a/doc/opal-api/opal-xscom-read-write-65-66.txt
> +++ b/doc/opal-api/opal-xscom-read-write-65-66.txt
> @@ -10,3 +10,8 @@ each takes three parameters:
>  
>  int xscom_read(uint32_t partid, uint64_t pcb_addr, uint64_t *val)
>  int xscom_write(uint32_t partid, uint64_t pcb_addr, uint64_t val)
> +
> +Returns:
> +	OPAL_SUCCESS
> +	OPAL_HARDWARE if operation failed
> +	OPAL_WRONG_STATE if CPU is asleep
> diff --git a/hw/xscom.c b/hw/xscom.c
> index a7a1705..1c45cbc 100644
> --- a/hw/xscom.c
> +++ b/hw/xscom.c
> @@ -118,7 +118,7 @@ static void xscom_reset(uint32_t gcid)
>  	 */
>  }
>  
> -static bool xscom_handle_error(uint64_t hmer, uint32_t gcid, uint32_t 
pcb_addr,
> +static int xscom_handle_error(uint64_t hmer, uint32_t gcid, uint32_t 
pcb_addr,
>  			       bool is_write)
>  {
>  	unsigned int stat = GETFIELD(SPR_HMER_XSCOM_STATUS, hmer);
> @@ -129,7 +129,10 @@ static bool xscom_handle_error(uint64_t hmer, uint32_t 
gcid, uint32_t pcb_addr,
>  	switch(stat) {
>  	/* XSCOM blocked, just retry */
>  	case 1:
> -		return true;
> +		return OPAL_BUSY;
> +	/* CPU is asleep, don't retry */
> +	case 2:
> +		return OPAL_WRONG_STATE;
>  	}
>  
>  	/* XXX: Create error log entry ? */
> @@ -141,7 +144,7 @@ static bool xscom_handle_error(uint64_t hmer, uint32_t 
gcid, uint32_t pcb_addr,
>  	xscom_reset(gcid);
>  
>  	/* Non recovered ... just fail */
> -	return false;
> +	return OPAL_HARDWARE;
>  }
>  
>  static void xscom_handle_ind_error(uint64_t data, uint32_t gcid,
> @@ -175,6 +178,7 @@ static bool xscom_gcid_ok(uint32_t gcid)
>  static int __xscom_read(uint32_t gcid, uint32_t pcb_addr, uint64_t *val)
>  {
>  	uint64_t hmer;
> +	int64_t ret;
>  
>  	if (!xscom_gcid_ok(gcid)) {
>  		prerror("%s: invalid XSCOM gcid 0x%x\n", __func__, gcid);
> @@ -197,16 +201,18 @@ static int __xscom_read(uint32_t gcid, uint32_t 
pcb_addr, uint64_t *val)
>  		if (!(hmer & SPR_HMER_XSCOM_FAIL))
>  			break;
>  
> -		/* Handle error and eventually retry */
> -		if (!xscom_handle_error(hmer, gcid, pcb_addr, false))
> -			return OPAL_HARDWARE;
> +		/* Handle error and possibly eventually retry */
> +		ret = xscom_handle_error(hmer, gcid, pcb_addr, false);
> +		if (ret == OPAL_HARDWARE || ret == OPAL_WRONG_STATE)
> +			return ret;
>  	}
> -	return 0;
> +	return OPAL_SUCCESS;
>  }
>  
>  static int __xscom_write(uint32_t gcid, uint32_t pcb_addr, uint64_t val)
>  {
>  	uint64_t hmer;
> +	int64_t ret;
>  
>  	if (!xscom_gcid_ok(gcid)) {
>  		prerror("%s: invalid XSCOM gcid 0x%x\n", __func__, gcid);
> @@ -229,11 +235,12 @@ static int __xscom_write(uint32_t gcid, uint32_t 
pcb_addr, uint64_t val)
>  		if (!(hmer & SPR_HMER_XSCOM_FAIL))
>  			break;
>  
> -		/* Handle error and eventually retry */
> -		if (!xscom_handle_error(hmer, gcid, pcb_addr, true))
> -			return OPAL_HARDWARE;
> +		/* Handle error and possibly eventually retry */
> +		ret = xscom_handle_error(hmer, gcid, pcb_addr, true);
> +		if (ret == OPAL_HARDWARE || ret == OPAL_WRONG_STATE)
> +			return ret;
>  	}
> -	return 0;
> +	return OPAL_SUCCESS;
>  }
>  
>  /*
> 




More information about the Skiboot mailing list