[PATCH linux dev-4.10 v2] drivers (fsi): sbefifo: Add timeout for waiting for data
Brad Bishop
bradleyb at fuzziesquirrel.com
Tue Oct 31 03:22:45 AEDT 2017
> On Oct 26, 2017, at 6:34 PM, Eddie James <eajames at linux.vnet.ibm.com> wrote:
>
> From: "Edward A. James" <eajames at us.ibm.com>
>
> During a transfer, in the event that the SBE isn't running, the driver
> will wait for data to appear in the FIFO forever. This doesn't work at
> BMC boot time if any transfers are attempted (by OCC driver probing, for
> example), as it will just hang the boot. So add a simple timeout
> mechanism when the driver reschdules waiting for data to show up in the
> FIFO.
>
> Tested on witherspoon by rebooting the BMC successfully with chassis
> power on.
>
> Signed-off-by: Edward A. James <eajames at us.ibm.com>
> ---
> Changes since v1:
> * Reset the wait_data_timeout field if we get data. If we get data, the SBE
> is running and we really shouldn't timeout.
>
> drivers/fsi/fsi-sbefifo.c | 18 ++++++++++++++++++
> 1 file changed, 18 insertions(+)
>
> diff --git a/drivers/fsi/fsi-sbefifo.c b/drivers/fsi/fsi-sbefifo.c
> index f756822..41b838e 100644
> --- a/drivers/fsi/fsi-sbefifo.c
> +++ b/drivers/fsi/fsi-sbefifo.c
> @@ -54,6 +54,7 @@
> #define SBEFIFO_EOT_ACK 0x14
>
> #define SBEFIFO_RESCHEDULE msecs_to_jiffies(500)
> +#define SBEFIFO_MAX_RESCHDULE msecs_to_jiffies(5000)
>
> struct sbefifo {
> struct timer_list poll_timer;
> @@ -77,6 +78,7 @@ struct sbefifo_buf {
> };
>
> struct sbefifo_xfr {
> + unsigned long wait_data_timeout;
> struct sbefifo_buf *rbuf;
> struct sbefifo_buf *wbuf;
> struct list_head client;
> @@ -450,11 +452,27 @@ static void sbefifo_poll_timer(unsigned long data)
>
> devn = sbefifo_dev_nwreadable(sts);
> if (devn == 0) {
> + /*
> + * Limit the maximum waiting period for data in the
> + * FIFO. If the SBE isn't running, we will wait
> + * forever.
> + */
> + if (!xfr->wait_data_timeout) {
> + xfr->wait_data_timeout =
> + jiffies + SBEFIFO_MAX_RESCHDULE;
> + } else if (time_after(jiffies,
> + xfr->wait_data_timeout)) {
> + ret = -ETIME;
> + goto out;
> + }
> +
> /* No data yet. Reschedule. */
> sbefifo->poll_timer.expires = jiffies +
> SBEFIFO_RESCHEDULE;
> add_timer(&sbefifo->poll_timer);
> goto out_unlock;
> + } else {
> + xfr->wait_data_timeout = 0;
> }
>
> /* Fill. The EOT word is discarded. */
> --
> 1.8.3.1
I think I chose this wait forever approach because I figured user space could
use nonblock + epoll if they didn’t want to wait forever. Rationale being the
kernel should provide access and not dictate policy.
But userspace isn’t the problem here, its the in-kernel api being used by
other drivers.
The only other idea I have here if we don’t like this patch is to make the in-kernel
API never block (or provide a non-blocking version of it), but I vaguely remember
that already being discussed and deemed un-optimal for other reasons.
-brad
More information about the openbmc
mailing list