diff options
author | Mete Durlu <meted@linux.ibm.com> | 2024-07-04 14:10:08 +0200 |
---|---|---|
committer | Vasily Gorbik <gor@linux.ibm.com> | 2024-07-10 19:50:45 +0200 |
commit | f4493954215ceb8b22aca3ee6b10c6172f20a9fc (patch) | |
tree | 0e05b5054b2d3376ba8a111c492f28c267bd94a3 | |
parent | 97999f8c62a43cf2af5d725b045b82f9b47d83ea (diff) |
s390/hypfs_diag: Diag204 busy loop
When diag204 busy-indiciation facility is installed and diag204 is
returning busy, hypfs diag204 handler now does an interruptable busy
wait until diag204 is no longer busy. If there is a signal pending, call
would be restarted with -ERESTARTSYSCALL, except for fatal signals.
Acked-by: Heiko Carstens <hca@linux.ibm.com>
Reviewed-by: Tobias Huschle <huschle@linux.ibm.com>
Signed-off-by: Mete Durlu <meted@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
-rw-r--r-- | arch/s390/hypfs/hypfs_dbfs.c | 4 | ||||
-rw-r--r-- | arch/s390/hypfs/hypfs_diag.c | 17 | ||||
-rw-r--r-- | arch/s390/include/asm/diag.h | 1 |
3 files changed, 18 insertions, 4 deletions
diff --git a/arch/s390/hypfs/hypfs_dbfs.c b/arch/s390/hypfs/hypfs_dbfs.c index 4024599eb448..0e855c5e91c5 100644 --- a/arch/s390/hypfs/hypfs_dbfs.c +++ b/arch/s390/hypfs/hypfs_dbfs.c @@ -39,7 +39,9 @@ static ssize_t dbfs_read(struct file *file, char __user *buf, return 0; df = file_inode(file)->i_private; - mutex_lock(&df->lock); + if (mutex_lock_interruptible(&df->lock)) + return -ERESTARTSYS; + data = hypfs_dbfs_data_alloc(df); if (!data) { mutex_unlock(&df->lock); diff --git a/arch/s390/hypfs/hypfs_diag.c b/arch/s390/hypfs/hypfs_diag.c index 279b7bba4d43..26a009f9c49e 100644 --- a/arch/s390/hypfs/hypfs_diag.c +++ b/arch/s390/hypfs/hypfs_diag.c @@ -140,11 +140,22 @@ fail_alloc: int diag204_store(void *buf, int pages) { + unsigned long subcode; int rc; - rc = diag204((unsigned long)diag204_store_sc | - (unsigned long)diag204_get_info_type(), pages, buf); - return rc < 0 ? -EOPNOTSUPP : 0; + subcode = diag204_get_info_type(); + subcode |= diag204_store_sc; + if (diag204_has_bif()) + subcode |= DIAG204_BIF_BIT; + while (1) { + rc = diag204(subcode, pages, buf); + if (rc != -EBUSY) + break; + if (signal_pending(current)) + return -ERESTARTSYS; + schedule_timeout_interruptible(DIAG204_BUSY_WAIT); + } + return rc < 0 ? rc : 0; } struct dbfs_d204_hdr { diff --git a/arch/s390/include/asm/diag.h b/arch/s390/include/asm/diag.h index 6527d7e8e010..c0d43512f4fc 100644 --- a/arch/s390/include/asm/diag.h +++ b/arch/s390/include/asm/diag.h @@ -119,6 +119,7 @@ enum diag204_sc { #define DIAG204_SUBCODE_MASK 0xffff #define DIAG204_BIF_BIT 0x80000000 +#define DIAG204_BUSY_WAIT (HZ / 10) /* The two available diag 204 data formats */ enum diag204_format { |