[RFC PATCH v2 8/9] hyper_dmabuf: event-polling mechanism for detecting a new hyper_DMABUF

2018-02-13 Thread Dongwon Kim
New method based on polling for a importing VM to know about a new
hyper_DMABUF exported to it.

For this, the userspace now can poll the device node to check if
there a new event, which is created if there's a new hyper_DMABUF
available in importing VM (just exported).

A poll function call was added to the device driver interface for this
new functionality. Event-generation functionalitywas also implemented in
all other relavant parts of driver.

This "event-polling" mechanism is optional feature and can be enabled
by setting a Kernel config option, "HYPER_DMABUF_EVENT_GEN".

Signed-off-by: Dongwon Kim 
Signed-off-by: Mateusz Polrola 
---
 drivers/dma-buf/hyper_dmabuf/Kconfig  |  20 +++
 drivers/dma-buf/hyper_dmabuf/Makefile |   1 +
 drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_drv.c   | 146 ++
 drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_drv.h   |  11 ++
 drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_event.c | 122 ++
 drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_event.h |  38 ++
 drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_list.c  |   1 +
 drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_msg.c   |  11 ++
 include/uapi/linux/hyper_dmabuf.h |  11 ++
 9 files changed, 361 insertions(+)
 create mode 100644 drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_event.c
 create mode 100644 drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_event.h

diff --git a/drivers/dma-buf/hyper_dmabuf/Kconfig 
b/drivers/dma-buf/hyper_dmabuf/Kconfig
index 68f3d6ce2c1f..92510731af25 100644
--- a/drivers/dma-buf/hyper_dmabuf/Kconfig
+++ b/drivers/dma-buf/hyper_dmabuf/Kconfig
@@ -20,6 +20,16 @@ config HYPER_DMABUF_SYSFS
 
  The location of sysfs is under ""
 
+config HYPER_DMABUF_EVENT_GEN
+bool "Enable event-generation and polling operation"
+default n
+depends on HYPER_DMABUF
+help
+  With this config enabled, hyper_dmabuf driver on the importer side
+  generates events and queue those up in the event list whenever a new
+  shared DMA-BUF is available. Events in the list can be retrieved by
+  read operation.
+
 config HYPER_DMABUF_XEN
 bool "Configure hyper_dmabuf for XEN hypervisor"
 default y
@@ -27,4 +37,14 @@ config HYPER_DMABUF_XEN
 help
   Enabling Hyper_DMABUF Backend for XEN hypervisor
 
+config HYPER_DMABUF_XEN_AUTO_RX_CH_ADD
+bool "Enable automatic rx-ch add with 10 secs interval"
+default y
+depends on HYPER_DMABUF && HYPER_DMABUF_XEN
+help
+  If enabled, driver reads a node in xenstore every 10 seconds
+  to check whether there is any tx comm ch configured by another
+  domain then initialize matched rx comm ch automatically for any
+  existing tx comm chs.
+
 endmenu
diff --git a/drivers/dma-buf/hyper_dmabuf/Makefile 
b/drivers/dma-buf/hyper_dmabuf/Makefile
index 578a669a0d3e..f573dd5c4054 100644
--- a/drivers/dma-buf/hyper_dmabuf/Makefile
+++ b/drivers/dma-buf/hyper_dmabuf/Makefile
@@ -11,6 +11,7 @@ ifneq ($(KERNELRELEASE),)
 hyper_dmabuf_id.o \
 hyper_dmabuf_remote_sync.o \
 hyper_dmabuf_query.o \
+hyper_dmabuf_event.o \
 
 ifeq ($(CONFIG_HYPER_DMABUF_XEN), y)
$(TARGET_MODULE)-objs += backends/xen/hyper_dmabuf_xen_comm.o \
diff --git a/drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_drv.c 
b/drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_drv.c
index 3320f9dcc769..087f091ccae9 100644
--- a/drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_drv.c
+++ b/drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_drv.c
@@ -41,6 +41,7 @@
 #include "hyper_dmabuf_ioctl.h"
 #include "hyper_dmabuf_list.h"
 #include "hyper_dmabuf_id.h"
+#include "hyper_dmabuf_event.h"
 
 #ifdef CONFIG_HYPER_DMABUF_XEN
 #include "backends/xen/hyper_dmabuf_xen_drv.h"
@@ -91,10 +92,138 @@ static int hyper_dmabuf_release(struct inode *inode, 
struct file *filp)
return 0;
 }
 
+#ifdef CONFIG_HYPER_DMABUF_EVENT_GEN
+
+static unsigned int hyper_dmabuf_event_poll(struct file *filp,
+struct poll_table_struct *wait)
+{
+   poll_wait(filp, _drv_priv->event_wait, wait);
+
+   if (!list_empty(_drv_priv->event_list))
+   return POLLIN | POLLRDNORM;
+
+   return 0;
+}
+
+static ssize_t hyper_dmabuf_event_read(struct file *filp, char __user *buffer,
+   size_t count, loff_t *offset)
+{
+   int ret;
+
+   /* only root can read events */
+   if (!capable(CAP_DAC_OVERRIDE)) {
+   dev_err(hy_drv_priv->dev,
+   "Only root can read events\n");
+   return -EPERM;
+   }
+
+   /* make sure user buffer can be written */
+   if (!access_ok(VERIFY_WRITE, buffer, count)) {
+   dev_err(hy_drv_priv->dev,
+   "User buffer can't be 

[RFC PATCH v2 8/9] hyper_dmabuf: event-polling mechanism for detecting a new hyper_DMABUF

2018-02-13 Thread Dongwon Kim
New method based on polling for a importing VM to know about a new
hyper_DMABUF exported to it.

For this, the userspace now can poll the device node to check if
there a new event, which is created if there's a new hyper_DMABUF
available in importing VM (just exported).

A poll function call was added to the device driver interface for this
new functionality. Event-generation functionalitywas also implemented in
all other relavant parts of driver.

This "event-polling" mechanism is optional feature and can be enabled
by setting a Kernel config option, "HYPER_DMABUF_EVENT_GEN".

Signed-off-by: Dongwon Kim 
Signed-off-by: Mateusz Polrola 
---
 drivers/dma-buf/hyper_dmabuf/Kconfig  |  20 +++
 drivers/dma-buf/hyper_dmabuf/Makefile |   1 +
 drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_drv.c   | 146 ++
 drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_drv.h   |  11 ++
 drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_event.c | 122 ++
 drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_event.h |  38 ++
 drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_list.c  |   1 +
 drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_msg.c   |  11 ++
 include/uapi/linux/hyper_dmabuf.h |  11 ++
 9 files changed, 361 insertions(+)
 create mode 100644 drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_event.c
 create mode 100644 drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_event.h

diff --git a/drivers/dma-buf/hyper_dmabuf/Kconfig 
b/drivers/dma-buf/hyper_dmabuf/Kconfig
index 68f3d6ce2c1f..92510731af25 100644
--- a/drivers/dma-buf/hyper_dmabuf/Kconfig
+++ b/drivers/dma-buf/hyper_dmabuf/Kconfig
@@ -20,6 +20,16 @@ config HYPER_DMABUF_SYSFS
 
  The location of sysfs is under ""
 
+config HYPER_DMABUF_EVENT_GEN
+bool "Enable event-generation and polling operation"
+default n
+depends on HYPER_DMABUF
+help
+  With this config enabled, hyper_dmabuf driver on the importer side
+  generates events and queue those up in the event list whenever a new
+  shared DMA-BUF is available. Events in the list can be retrieved by
+  read operation.
+
 config HYPER_DMABUF_XEN
 bool "Configure hyper_dmabuf for XEN hypervisor"
 default y
@@ -27,4 +37,14 @@ config HYPER_DMABUF_XEN
 help
   Enabling Hyper_DMABUF Backend for XEN hypervisor
 
+config HYPER_DMABUF_XEN_AUTO_RX_CH_ADD
+bool "Enable automatic rx-ch add with 10 secs interval"
+default y
+depends on HYPER_DMABUF && HYPER_DMABUF_XEN
+help
+  If enabled, driver reads a node in xenstore every 10 seconds
+  to check whether there is any tx comm ch configured by another
+  domain then initialize matched rx comm ch automatically for any
+  existing tx comm chs.
+
 endmenu
diff --git a/drivers/dma-buf/hyper_dmabuf/Makefile 
b/drivers/dma-buf/hyper_dmabuf/Makefile
index 578a669a0d3e..f573dd5c4054 100644
--- a/drivers/dma-buf/hyper_dmabuf/Makefile
+++ b/drivers/dma-buf/hyper_dmabuf/Makefile
@@ -11,6 +11,7 @@ ifneq ($(KERNELRELEASE),)
 hyper_dmabuf_id.o \
 hyper_dmabuf_remote_sync.o \
 hyper_dmabuf_query.o \
+hyper_dmabuf_event.o \
 
 ifeq ($(CONFIG_HYPER_DMABUF_XEN), y)
$(TARGET_MODULE)-objs += backends/xen/hyper_dmabuf_xen_comm.o \
diff --git a/drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_drv.c 
b/drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_drv.c
index 3320f9dcc769..087f091ccae9 100644
--- a/drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_drv.c
+++ b/drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_drv.c
@@ -41,6 +41,7 @@
 #include "hyper_dmabuf_ioctl.h"
 #include "hyper_dmabuf_list.h"
 #include "hyper_dmabuf_id.h"
+#include "hyper_dmabuf_event.h"
 
 #ifdef CONFIG_HYPER_DMABUF_XEN
 #include "backends/xen/hyper_dmabuf_xen_drv.h"
@@ -91,10 +92,138 @@ static int hyper_dmabuf_release(struct inode *inode, 
struct file *filp)
return 0;
 }
 
+#ifdef CONFIG_HYPER_DMABUF_EVENT_GEN
+
+static unsigned int hyper_dmabuf_event_poll(struct file *filp,
+struct poll_table_struct *wait)
+{
+   poll_wait(filp, _drv_priv->event_wait, wait);
+
+   if (!list_empty(_drv_priv->event_list))
+   return POLLIN | POLLRDNORM;
+
+   return 0;
+}
+
+static ssize_t hyper_dmabuf_event_read(struct file *filp, char __user *buffer,
+   size_t count, loff_t *offset)
+{
+   int ret;
+
+   /* only root can read events */
+   if (!capable(CAP_DAC_OVERRIDE)) {
+   dev_err(hy_drv_priv->dev,
+   "Only root can read events\n");
+   return -EPERM;
+   }
+
+   /* make sure user buffer can be written */
+   if (!access_ok(VERIFY_WRITE, buffer, count)) {
+   dev_err(hy_drv_priv->dev,
+   "User buffer can't be written.\n");
+   return -EINVAL;
+   }