diff mbox

[PATCHv5,1/2] xenbus: fix deadlock on writes to /proc/xen/xenbus

Message ID 1479121976-26568-2-git-send-email-david.vrabel@citrix.com (mailing list archive)
State New, archived
Headers show

Commit Message

David Vrabel Nov. 14, 2016, 11:12 a.m. UTC
/proc/xen/xenbus does not work correctly.  A read blocked waiting for
a xenstore message holds the mutex needed for atomic file position
updates.  This blocks any writes on the same file handle, which can
deadlock if the write is needed to unblock the read.

Clear FMODE_ATOMIC_POS when opening this device to always get
character device like sematics.

Signed-off-by: David Vrabel <david.vrabel@citrix.com>
---
 drivers/xen/xenbus/xenbus_dev_frontend.c | 2 ++
 1 file changed, 2 insertions(+)

Comments

Jan Beulich Nov. 14, 2016, 11:33 a.m. UTC | #1
>>> On 14.11.16 at 12:12, <david.vrabel@citrix.com> wrote:
> /proc/xen/xenbus does not work correctly.  A read blocked waiting for
> a xenstore message holds the mutex needed for atomic file position
> updates.  This blocks any writes on the same file handle, which can
> deadlock if the write is needed to unblock the read.
> 
> Clear FMODE_ATOMIC_POS when opening this device to always get
> character device like sematics.

Interesting. I'm pretty sure that back in March/April, when I had
to deal with this for our kernels, I was told the upstream kernel is
unaffected. In any event I continue to think that
https://patchwork.kernel.org/patch/8752901/
is the better (because more generic) solution here.

> --- a/drivers/xen/xenbus/xenbus_dev_frontend.c
> +++ b/drivers/xen/xenbus/xenbus_dev_frontend.c
> @@ -536,6 +536,8 @@ static int xenbus_file_open(struct inode *inode, struct file *filp)
>  	if (xen_store_evtchn == 0)
>  		return -ENOENT;
>  
> +	filp->f_mode &= ~FMODE_ATOMIC_POS; /* cdev-style semantics */
> +
>  	nonseekable_open(inode, filp);

In any event I think the adjustment should be placed after the call
to nonseekable_open(), despite it being unlikely that the function
might set the bit again.

Jan
diff mbox

Patch

diff --git a/drivers/xen/xenbus/xenbus_dev_frontend.c b/drivers/xen/xenbus/xenbus_dev_frontend.c
index 1e8be12..ce389b4 100644
--- a/drivers/xen/xenbus/xenbus_dev_frontend.c
+++ b/drivers/xen/xenbus/xenbus_dev_frontend.c
@@ -536,6 +536,8 @@  static int xenbus_file_open(struct inode *inode, struct file *filp)
 	if (xen_store_evtchn == 0)
 		return -ENOENT;
 
+	filp->f_mode &= ~FMODE_ATOMIC_POS; /* cdev-style semantics */
+
 	nonseekable_open(inode, filp);
 
 	u = kzalloc(sizeof(*u), GFP_KERNEL);