|
9 | 9 | #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
|
10 | 10 |
|
11 | 11 | #include <linux/completion.h>
|
| 12 | +#include <linux/jiffies.h> |
12 | 13 | #include <linux/kobject.h>
|
13 | 14 | #include <linux/list.h>
|
14 | 15 | #include <linux/printk.h>
|
|
28 | 29 |
|
29 | 30 | #define SD_DI_CONFIG 3
|
30 | 31 |
|
| 32 | +#define SD_TIMEOUT msecs_to_jiffies(30000) |
| 33 | + |
31 | 34 | struct sclp_sd_evbuf {
|
32 | 35 | struct evbuf_header hdr;
|
33 | 36 | u8 eq;
|
@@ -234,9 +237,12 @@ static int sclp_sd_sync(unsigned long page, u8 eq, u8 di, u64 sat, u64 sa,
|
234 | 237 | goto out;
|
235 | 238 | }
|
236 | 239 | 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) |
239 | 244 | goto out;
|
| 245 | + rc = 0; |
240 | 246 | evbuf = &listener.evbuf;
|
241 | 247 | }
|
242 | 248 | switch (evbuf->status) {
|
@@ -323,8 +329,8 @@ static int sclp_sd_store_data(struct sclp_sd_data *result, u8 di)
|
323 | 329 | rc = sclp_sd_sync(page, SD_EQ_STORE_DATA, di, asce, (u64) data, &dsize,
|
324 | 330 | &esize);
|
325 | 331 | 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) { |
328 | 334 | if (sclp_sd_sync(page, SD_EQ_HALT, di, 0, 0, NULL, NULL)) {
|
329 | 335 | pr_warn("Could not stop Store Data request - leaking at least %zu bytes\n",
|
330 | 336 | (size_t)dsize * PAGE_SIZE);
|
|
0 commit comments