summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHaren Myneni <haren@linux.ibm.com>2025-09-09 01:43:58 -0700
committerMadhavan Srinivasan <maddy@linux.ibm.com>2025-09-15 13:38:40 +0530
commitda24fb99a1b5cc842b9446f67f6bcda36b49817f (patch)
tree8c8b3e3c20dcbd30707aac4062a150641aafbfc2
parentcebdb522fd3edd1fe05f7b4a74a27da7dd0f8d86 (diff)
downloadlinux-da24fb99a1b5cc842b9446f67f6bcda36b49817f.tar.gz
linux-da24fb99a1b5cc842b9446f67f6bcda36b49817f.zip
powerpc/pseries: Wakeup hvpipe FD when the payload is pending
The user space polls on the wait_queue for the payload from the specific source. The hypervisor interrupts the OS when the pipe status for the specific source is changed such as payload is available for the partition or pipe to the source is closed. The OS retrieves the HVPIPE event message with check-exception RTAS and event message contains the source ID and the pipe status. Then wakes up all FDs waiting on the wait_queue so that the user space can read the payload or close the FD if the pipe to source in the hypervisor is closed. The hypervisor assigns one pipe per partition for all sources. Hence issue ibm,receive-hvpipe-msg() to read the pending payload during release() before closing FD so that pipe to the partition will not be blocked. Signed-off-by: Haren Myneni <haren@linux.ibm.com> Tested-by: Shashank MS <shashank.gowda@in.ibm.com> Reviewed-by: Mahesh Salgaonkar <mahesh@linux.ibm.com> Reviewed-by: Tyrel Datwyler <tyreld@linux.ibm.com> Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com> Link: https://patch.msgid.link/20250909084402.1488456-7-haren@linux.ibm.com
-rw-r--r--arch/powerpc/platforms/pseries/papr-hvpipe.c28
1 files changed, 27 insertions, 1 deletions
diff --git a/arch/powerpc/platforms/pseries/papr-hvpipe.c b/arch/powerpc/platforms/pseries/papr-hvpipe.c
index 87deb429b331..4a1444a0d331 100644
--- a/arch/powerpc/platforms/pseries/papr-hvpipe.c
+++ b/arch/powerpc/platforms/pseries/papr-hvpipe.c
@@ -396,6 +396,21 @@ static __poll_t papr_hvpipe_handle_poll(struct file *filp,
if (!src_info)
return POLLNVAL;
+ /*
+ * If hvpipe already has pending payload, return so that
+ * the user space can issue read().
+ */
+ if (src_info->hvpipe_status)
+ return POLLIN | POLLRDNORM;
+
+ /*
+ * Wait for the message event
+ * hvpipe_event_interrupt() wakes up this wait_queue
+ */
+ poll_wait(filp, &src_info->recv_wqh, wait);
+ if (src_info->hvpipe_status)
+ return POLLIN | POLLRDNORM;
+
return 0;
}
@@ -413,7 +428,18 @@ static int papr_hvpipe_handle_release(struct inode *inode,
src_info = file->private_data;
list_del(&src_info->list);
file->private_data = NULL;
- spin_unlock(&hvpipe_src_list_lock);
+ /*
+ * If the pipe for this specific source has any pending
+ * payload, issue recv HVPIPE RTAS so that pipe will not
+ * be blocked.
+ */
+ if (src_info->hvpipe_status & HVPIPE_MSG_AVAILABLE) {
+ src_info->hvpipe_status = 0;
+ spin_unlock(&hvpipe_src_list_lock);
+ hvpipe_rtas_recv_msg(NULL, 0);
+ } else
+ spin_unlock(&hvpipe_src_list_lock);
+
kfree(src_info);
return 0;
}