[Skiboot] [PATCH 04/11] libflash/mbox-flash: Allow mbox-flash to tell the driver msg timeouts

Samuel Mendoza-Jonas sam at mendozajonas.com
Fri Jul 14 14:03:19 AEST 2017


On Thu, 2017-06-29 at 22:39 +1000, Cyril Bur wrote:
> Currently when mbox-flash decides that a message times out the driver
> has no way of knowing to drop the message and will continue waiting for
> a response indefinitely preventing more messages from ever being sent.
> 
> This is a problem if the BMC crashes or has some other issue where it
> won't ever respond to our outstanding message.
> 
> This patch provides a method for mbox-flash to tell the driver how long
> it should wait before it no longer needs to care about the response.
> 
> Signed-off-by: Cyril Bur <cyril.bur at au1.ibm.com>
> ---
>  hw/lpc-mbox.c         | 12 +++++++++---
>  include/lpc-mbox.h    |  2 +-
>  libflash/mbox-flash.c | 17 +++++++++--------
>  3 files changed, 19 insertions(+), 12 deletions(-)
> 
> diff --git a/hw/lpc-mbox.c b/hw/lpc-mbox.c
> index 74214938..f303f4d5 100644
> --- a/hw/lpc-mbox.c
> +++ b/hw/lpc-mbox.c
> @@ -64,6 +64,7 @@ struct mbox {
>  	struct lock lock; /* Protect in_flight */
>  	struct bmc_mbox_msg *in_flight;
>  	uint8_t sequence;
> +	unsigned long timeout;
>  };
>  
>  static struct mbox mbox;
> @@ -115,7 +116,7 @@ static void bmc_mbox_send_message(struct bmc_mbox_msg *msg)
>  	bmc_mbox_outb(MBOX_CTRL_INT_SEND, MBOX_HOST_CTRL);
>  }
>  
> -int bmc_mbox_enqueue(struct bmc_mbox_msg *msg)
> +int bmc_mbox_enqueue(struct bmc_mbox_msg *msg, unsigned int timeout_sec)

Is there a benefit to specifying timeout_sec on every call to
bmc_mbox_enqueue / msg_send, vs setting it in eg. the mbox struct?

>  {
>  	if (!mbox.base) {
>  		prlog(PR_CRIT, "Using MBOX without init!\n");
> @@ -125,10 +126,15 @@ int bmc_mbox_enqueue(struct bmc_mbox_msg *msg)
>  	lock(&mbox.lock);
>  	if (mbox.in_flight) {
>  		prlog(PR_DEBUG, "MBOX message already in flight\n");
> -		unlock(&mbox.lock);
> -		return OPAL_BUSY;
> +		if (mftb() > mbox.timeout) {
> +			prlog(PR_ERR, "In flight message dropped on the floor\n");
> +		} else {
> +			unlock(&mbox.lock);
> +			return OPAL_BUSY;
> +		}
>  	}
>  
> +	mbox.timeout = mftb() + secs_to_tb(timeout_sec);
>  	mbox.in_flight = msg;
>  	unlock(&mbox.lock);
>  	msg->seq = ++mbox.sequence;
> diff --git a/include/lpc-mbox.h b/include/lpc-mbox.h
> index c4b1015b..569f1f72 100644
> --- a/include/lpc-mbox.h
> +++ b/include/lpc-mbox.h
> @@ -63,7 +63,7 @@ struct bmc_mbox_msg {
>  	uint8_t bmc;
>  };
>  
> -int bmc_mbox_enqueue(struct bmc_mbox_msg *msg);
> +int bmc_mbox_enqueue(struct bmc_mbox_msg *msg, unsigned int timeout_sec);
>  int bmc_mbox_register_callback(void (*callback)(struct bmc_mbox_msg *msg, void *priv),
>  		void *drv_data);
>  int bmc_mbox_register_attn(void (*callback)(uint8_t bits, void *priv),
> diff --git a/libflash/mbox-flash.c b/libflash/mbox-flash.c
> index 90e6e860..2914901e 100644
> --- a/libflash/mbox-flash.c
> +++ b/libflash/mbox-flash.c
> @@ -252,13 +252,14 @@ static bool is_reboot(struct mbox_flash_data *mbox_flash)
>  	return mbox_flash->reboot;
>  }
>  
> -static int msg_send(struct mbox_flash_data *mbox_flash, struct bmc_mbox_msg *msg)
> +static int msg_send(struct mbox_flash_data *mbox_flash, struct bmc_mbox_msg *msg,
> +		unsigned int timeout_sec)
>  {
>  	if (is_reboot(mbox_flash))
>  		return FLASH_ERR_AGAIN;
>  	mbox_flash->busy = true;
>  	mbox_flash->rc = 0;
> -	return bmc_mbox_enqueue(msg);
> +	return bmc_mbox_enqueue(msg, timeout_sec);
>  }
>  
>  static int wait_for_bmc(struct mbox_flash_data *mbox_flash, unsigned int timeout_sec)
> @@ -307,7 +308,7 @@ static int mbox_flash_ack(struct mbox_flash_data *mbox_flash, uint8_t reg)
>  	/* Clear this first so msg_send() doesn't freak out */
>  	mbox_flash->reboot = false;
>  
> -	rc = msg_send(mbox_flash, msg);
> +	rc = msg_send(mbox_flash, msg, MBOX_DEFAULT_TIMEOUT);
>  
>  	/* Still need to deal with it, we've only acked it now. */
>  	mbox_flash->reboot = true;
> @@ -499,7 +500,7 @@ static int mbox_flash_mark_write(struct mbox_flash_data *mbox_flash,
>  		msg_put_u16(msg, 2, end - start); /* Total Length */
>  	}
>  
> -	rc = msg_send(mbox_flash, msg);
> +	rc = msg_send(mbox_flash, msg, MBOX_DEFAULT_TIMEOUT);
>  	if (rc) {
>  		prlog(PR_ERR, "Failed to enqueue/send BMC MBOX message\n");
>  		goto out;
> @@ -554,7 +555,7 @@ static int mbox_flash_flush(struct mbox_flash_data *mbox_flash)
>  	if (!msg)
>  		return FLASH_ERR_MALLOC_FAILED;
>  
> -	rc = msg_send(mbox_flash, msg);
> +	rc = msg_send(mbox_flash, msg, MBOX_DEFAULT_TIMEOUT);
>  	if (rc) {
>  		prlog(PR_ERR, "Failed to enqueue/send BMC MBOX message\n");
>  		goto out;
> @@ -609,7 +610,7 @@ static int mbox_window_move(struct mbox_flash_data *mbox_flash,
>  		return FLASH_ERR_MALLOC_FAILED;
>  
>  	msg_put_u16(msg, 0, bytes_to_blocks(mbox_flash, pos));
> -	rc = msg_send(mbox_flash, msg);
> +	rc = msg_send(mbox_flash, msg, MBOX_DEFAULT_TIMEOUT);
>  	if (rc) {
>  		prlog(PR_ERR, "Failed to enqueue/send BMC MBOX message\n");
>  		goto out;
> @@ -772,7 +773,7 @@ static int mbox_flash_get_info(struct blocklevel_device *bl, const char **name,
>  		*name = NULL;
>  
>  	mbox_flash->busy = true;
> -	rc = msg_send(mbox_flash, msg);
> +	rc = msg_send(mbox_flash, msg, MBOX_DEFAULT_TIMEOUT);
>  	if (rc) {
>  		prlog(PR_ERR, "Failed to enqueue/send BMC MBOX message\n");
>  		goto out;
> @@ -965,7 +966,7 @@ static int protocol_init(struct mbox_flash_data *mbox_flash)
>  		return FLASH_ERR_MALLOC_FAILED;
>  
>  	msg_put_u8(msg, 0, mbox_flash->version);
> -	rc = msg_send(mbox_flash, msg);
> +	rc = msg_send(mbox_flash, msg, MBOX_DEFAULT_TIMEOUT);
>  	if (rc) {
>  		prlog(PR_ERR, "Failed to enqueue/send BMC MBOX message\n");
>  		goto out;



More information about the Skiboot mailing list