Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

fsi: sbefifo: Add configurable in-command timeout

A new use case for the SBEFIFO requires a long in-command timeout
as the SBE processes each part of the command before clearing the
upstream FIFO for the next part of the command.

Signed-off-by: Eddie James <eajames@linux.ibm.com>
Link: https://lore.kernel.org/r/20230612195657.245125-6-eajames@linux.ibm.com
Signed-off-by: Joel Stanley <joel@jms.id.au>

authored by

Eddie James and committed by
Joel Stanley
19c064de d6ce872e

+39 -1
+29 -1
drivers/fsi/fsi-sbefifo.c
··· 127 127 bool dead; 128 128 bool async_ffdc; 129 129 bool timed_out; 130 + u32 timeout_in_cmd_ms; 130 131 u32 timeout_start_rsp_ms; 131 132 }; 132 133 ··· 137 136 void *cmd_page; 138 137 void *pending_cmd; 139 138 size_t pending_len; 139 + u32 cmd_timeout_ms; 140 140 u32 read_timeout_ms; 141 141 }; 142 142 ··· 510 508 rc = sbefifo_wait(sbefifo, true, &status, timeout); 511 509 if (rc < 0) 512 510 return rc; 513 - timeout = msecs_to_jiffies(SBEFIFO_TIMEOUT_IN_CMD); 511 + timeout = msecs_to_jiffies(sbefifo->timeout_in_cmd_ms); 514 512 515 513 vacant = sbefifo_vacant(status); 516 514 len = chunk = min(vacant, remaining); ··· 804 802 return -ENOMEM; 805 803 } 806 804 mutex_init(&user->file_lock); 805 + user->cmd_timeout_ms = SBEFIFO_TIMEOUT_IN_CMD; 807 806 user->read_timeout_ms = SBEFIFO_TIMEOUT_START_RSP; 808 807 809 808 return 0; ··· 848 845 rc = mutex_lock_interruptible(&sbefifo->lock); 849 846 if (rc) 850 847 goto bail; 848 + sbefifo->timeout_in_cmd_ms = user->cmd_timeout_ms; 851 849 sbefifo->timeout_start_rsp_ms = user->read_timeout_ms; 852 850 rc = __sbefifo_submit(sbefifo, user->pending_cmd, cmd_len, &resp_iter); 853 851 sbefifo->timeout_start_rsp_ms = SBEFIFO_TIMEOUT_START_RSP; 852 + sbefifo->timeout_in_cmd_ms = SBEFIFO_TIMEOUT_IN_CMD; 854 853 mutex_unlock(&sbefifo->lock); 855 854 if (rc < 0) 856 855 goto bail; ··· 942 937 return 0; 943 938 } 944 939 940 + static int sbefifo_cmd_timeout(struct sbefifo_user *user, void __user *argp) 941 + { 942 + struct device *dev = &user->sbefifo->dev; 943 + u32 timeout; 944 + 945 + if (get_user(timeout, (__u32 __user *)argp)) 946 + return -EFAULT; 947 + 948 + if (timeout == 0) { 949 + user->cmd_timeout_ms = SBEFIFO_TIMEOUT_IN_CMD; 950 + dev_dbg(dev, "Command timeout reset to %us\n", user->cmd_timeout_ms / 1000); 951 + return 0; 952 + } 953 + 954 + user->cmd_timeout_ms = timeout * 1000; /* user timeout is in sec */ 955 + dev_dbg(dev, "Command timeout set to %us\n", timeout); 956 + return 0; 957 + } 958 + 945 959 static int sbefifo_read_timeout(struct sbefifo_user *user, void __user *argp) 946 960 { 947 961 struct device *dev = &user->sbefifo->dev; ··· 995 971 996 972 mutex_lock(&user->file_lock); 997 973 switch (cmd) { 974 + case FSI_SBEFIFO_CMD_TIMEOUT_SECONDS: 975 + rc = sbefifo_cmd_timeout(user, (void __user *)arg); 976 + break; 998 977 case FSI_SBEFIFO_READ_TIMEOUT_SECONDS: 999 978 rc = sbefifo_read_timeout(user, (void __user *)arg); 1000 979 break; ··· 1052 1025 sbefifo->fsi_dev = fsi_dev; 1053 1026 dev_set_drvdata(dev, sbefifo); 1054 1027 mutex_init(&sbefifo->lock); 1028 + sbefifo->timeout_in_cmd_ms = SBEFIFO_TIMEOUT_IN_CMD; 1055 1029 sbefifo->timeout_start_rsp_ms = SBEFIFO_TIMEOUT_START_RSP; 1056 1030 1057 1031 /* Create chardev for userspace access */
+10
include/uapi/linux/fsi.h
··· 60 60 */ 61 61 62 62 /** 63 + * FSI_SBEFIFO_CMD_TIMEOUT sets the timeout for writing data to the SBEFIFO. 64 + * 65 + * The command timeout is specified in seconds. The minimum value of command 66 + * timeout is 1 seconds (default) and the maximum value of command timeout is 67 + * 120 seconds. A command timeout of 0 will reset the value to the default of 68 + * 1 seconds. 69 + */ 70 + #define FSI_SBEFIFO_CMD_TIMEOUT_SECONDS _IOW('s', 0x01, __u32) 71 + 72 + /** 63 73 * FSI_SBEFIFO_READ_TIMEOUT sets the read timeout for response from SBE. 64 74 * 65 75 * The read timeout is specified in seconds. The minimum value of read