Skip to content

Commit bb748ba

Browse files
oberparAlexander Gordeev
authored andcommitted
s390/sclp: Add timeout to Store Data requests
Due to a bug in some firmware versions, Store Data requests might not get an event response in certain situations. As a result, the boot process will be blocked indefinitely. Fix this by introducing timeout handling for Store Data requests. In case a timeout occurs, the Store Data operation is halted and no data is retrieved from the SCLP facility. Note: A minority of installed systems rely on Store Data result for device auto-configuration. These systems will fail to boot in case of a Store Data timeout and will need to be switched to manual device configuration as workaround. Reviewed-by: Heiko Carstens <[email protected]> Signed-off-by: Peter Oberparleiter <[email protected]> Signed-off-by: Alexander Gordeev <[email protected]>
1 parent bf36507 commit bb748ba

File tree

1 file changed

+10
-4
lines changed

1 file changed

+10
-4
lines changed

drivers/s390/char/sclp_sd.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
1010

1111
#include <linux/completion.h>
12+
#include <linux/jiffies.h>
1213
#include <linux/kobject.h>
1314
#include <linux/list.h>
1415
#include <linux/printk.h>
@@ -28,6 +29,8 @@
2829

2930
#define SD_DI_CONFIG 3
3031

32+
#define SD_TIMEOUT msecs_to_jiffies(30000)
33+
3134
struct sclp_sd_evbuf {
3235
struct evbuf_header hdr;
3336
u8 eq;
@@ -234,9 +237,12 @@ static int sclp_sd_sync(unsigned long page, u8 eq, u8 di, u64 sat, u64 sa,
234237
goto out;
235238
}
236239
if (!(evbuf->rflags & 0x80)) {
237-
rc = wait_for_completion_interruptible(&listener.completion);
238-
if (rc)
240+
rc = wait_for_completion_interruptible_timeout(&listener.completion, SD_TIMEOUT);
241+
if (rc == 0)
242+
rc = -ETIME;
243+
if (rc < 0)
239244
goto out;
245+
rc = 0;
240246
evbuf = &listener.evbuf;
241247
}
242248
switch (evbuf->status) {
@@ -323,8 +329,8 @@ static int sclp_sd_store_data(struct sclp_sd_data *result, u8 di)
323329
rc = sclp_sd_sync(page, SD_EQ_STORE_DATA, di, asce, (u64) data, &dsize,
324330
&esize);
325331
if (rc) {
326-
/* Cancel running request if interrupted */
327-
if (rc == -ERESTARTSYS) {
332+
/* Cancel running request if interrupted or timed out */
333+
if (rc == -ERESTARTSYS || rc == -ETIME) {
328334
if (sclp_sd_sync(page, SD_EQ_HALT, di, 0, 0, NULL, NULL)) {
329335
pr_warn("Could not stop Store Data request - leaking at least %zu bytes\n",
330336
(size_t)dsize * PAGE_SIZE);

0 commit comments

Comments
 (0)