Re: [RFC v2 4/7] V4L: Events: Add backend

2010-01-22 Thread Sakari Ailus
Hans Verkuil wrote:
 Hi Sakari,

Hi, Hans!

 The code looks good, but I'm not so sure about the use of kmem_cache_*. It
 seems serious overkill to me.
 
 Most of the time there will only be a handful of event messages pending. So
 setting up a kmem_cache for this seems unnecessary to me.
 
 A much better way to ensure fast event reporting IMHO would be to keep a
 list
 of empty event messages rather than destroying an event after it is
 dequeued.
 
 So you have two queues per filehandle: pending and empty; initially both
 are
 empty. When a new event has to be queued the code checks if there are
 events
 available for reuse in the empty queue, and if not a new event struct is
 allocated and added to the pending queue.

I actually had this kind of setup there for a while. Then I thought it'd
be too ugly and went for kmem_cache instead.

The other reason is that it's convenient to keep the memory allocated
even if there are no events subscribed or the device isn't open. For
1000 events that's 96 kiB. I guess an unused kmem_cache object consumes
extra memory very little. The cached slabs can be explicitly freed
anyway by the driver.

The size of the kmem_cache also adjusts based on the number of events in
the queue. Allocating kmem_cache objects is fast if they already exist,
too. There can be temporary delays from allocation, of course.

I can bring it back, sure, if you see a fixed allocation better.

-- 
Sakari Ailus
sakari.ai...@maxwell.research.nokia.com
--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC v2 4/7] V4L: Events: Add backend

2010-01-18 Thread Hans Verkuil

Hi Sakari,

The code looks good, but I'm not so sure about the use of kmem_cache_*. It
seems serious overkill to me.

Most of the time there will only be a handful of event messages pending. So
setting up a kmem_cache for this seems unnecessary to me.

A much better way to ensure fast event reporting IMHO would be to keep a list
of empty event messages rather than destroying an event after it is dequeued.

So you have two queues per filehandle: pending and empty; initially both are
empty. When a new event has to be queued the code checks if there are events
available for reuse in the empty queue, and if not a new event struct is
allocated and added to the pending queue.

When userspace dequeues the event the kernel will not destroy the event struct
but requeue it in the empty queue for reuse. This is also an ideal place to
check for queue overflowing (which is definitely needed).

In general allocating memory is a slow operation, so not freeing that memory
will speed up things. Drivers might even preallocate a certain number of events
in the empty queue if the last drop of performance is needed.

But right now I don't think there is any need for that.

Regards,

  Hans

On Tue, 22 Dec 2009, Sakari Ailus wrote:


Add event handling backend to V4L2. The backend handles event subscription
and delivery to file handles. Event subscriptions are based on file handle.
Events may be delivered to all subscribed file handles on a device
independent of where they originate from.

Signed-off-by: Sakari Ailus sakari.ai...@maxwell.research.nokia.com
---
drivers/media/video/Makefile |3 +-
drivers/media/video/v4l2-dev.c   |   21 +++-
drivers/media/video/v4l2-event.c |  254 ++
drivers/media/video/v4l2-fh.c|4 +
include/media/v4l2-event.h   |   65 ++
include/media/v4l2-fh.h  |3 +
6 files changed, 346 insertions(+), 4 deletions(-)
create mode 100644 drivers/media/video/v4l2-event.c
create mode 100644 include/media/v4l2-event.h

diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index 1947146..dd6a853 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -10,7 +10,8 @@ stkwebcam-objs:=  stk-webcam.o stk-sensor.o

omap2cam-objs   :=  omap24xxcam.o omap24xxcam-dma.o

-videodev-objs  :=  v4l2-dev.o v4l2-ioctl.o v4l2-device.o v4l2-fh.o
+videodev-objs  :=  v4l2-dev.o v4l2-ioctl.o v4l2-device.o v4l2-fh.o \
+   v4l2-event.o

# V4L2 core modules

diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c
index 15b2ac8..6d25297 100644
--- a/drivers/media/video/v4l2-dev.c
+++ b/drivers/media/video/v4l2-dev.c
@@ -613,22 +613,36 @@ static int __init videodev_init(void)
dev_t dev = MKDEV(VIDEO_MAJOR, 0);
int ret;

+   ret = v4l2_event_init();
+   if (ret  0) {
+   printk(KERN_WARNING videodev: unable to initialise events\n);
+   return ret;
+   }
+
printk(KERN_INFO Linux video capture interface: v2.00\n);
ret = register_chrdev_region(dev, VIDEO_NUM_DEVICES, VIDEO_NAME);
if (ret  0) {
printk(KERN_WARNING videodev: unable to get major %d\n,
VIDEO_MAJOR);
-   return ret;
+   goto out_register_chrdev_region;
}

ret = class_register(video_class);
if (ret  0) {
-   unregister_chrdev_region(dev, VIDEO_NUM_DEVICES);
printk(KERN_WARNING video_dev: class_register failed\n);
-   return -EIO;
+   ret = -EIO;
+   goto out_class_register;
}

return 0;
+
+out_class_register:
+   unregister_chrdev_region(dev, VIDEO_NUM_DEVICES);
+
+out_register_chrdev_region:
+   v4l2_event_exit();
+
+   return ret;
}

static void __exit videodev_exit(void)
@@ -637,6 +651,7 @@ static void __exit videodev_exit(void)

class_unregister(video_class);
unregister_chrdev_region(dev, VIDEO_NUM_DEVICES);
+   v4l2_event_exit();
}

module_init(videodev_init)
diff --git a/drivers/media/video/v4l2-event.c b/drivers/media/video/v4l2-event.c
new file mode 100644
index 000..9fc0c81
--- /dev/null
+++ b/drivers/media/video/v4l2-event.c
@@ -0,0 +1,254 @@
+/*
+ * drivers/media/video/v4l2-event.c
+ *
+ * V4L2 events.
+ *
+ * Copyright (C) 2009 Nokia Corporation.
+ *
+ * Contact: Sakari Ailus sakari.ai...@maxwell.research.nokia.com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the 

Re: [RFC v2 4/7] V4L: Events: Add backend

2009-12-23 Thread Sakari Ailus

Hi Andy,

Andy Walls wrote:

+int v4l2_event_pending(struct v4l2_fh *fh)
+{
+   struct v4l2_events *events =fh-events;
+   unsigned long flags;
+   int ret;
+
+   spin_lock_irqsave(events-lock, flags);
+   ret = !list_empty(events-available);
+   spin_unlock_irqrestore(events-lock, flags);
+
+   return ret;
+}
+EXPORT_SYMBOL_GPL(v4l2_event_pending);


Hi Sakari,

Disabling and restoring local interrupts to check if any events are
pending seems excessive.

Since you added an atomic_t with the number of events available in patch
5/7, why don't you just check that atomic_t here?


Thanks for the comments!

I'll put the fix to patch 5.

--
Sakari Ailus
sakari.ai...@maxwell.research.nokia.com
--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC v2 4/7] V4L: Events: Add backend

2009-12-22 Thread Sakari Ailus
Add event handling backend to V4L2. The backend handles event subscription
and delivery to file handles. Event subscriptions are based on file handle.
Events may be delivered to all subscribed file handles on a device
independent of where they originate from.

Signed-off-by: Sakari Ailus sakari.ai...@maxwell.research.nokia.com
---
 drivers/media/video/Makefile |3 +-
 drivers/media/video/v4l2-dev.c   |   21 +++-
 drivers/media/video/v4l2-event.c |  254 ++
 drivers/media/video/v4l2-fh.c|4 +
 include/media/v4l2-event.h   |   65 ++
 include/media/v4l2-fh.h  |3 +
 6 files changed, 346 insertions(+), 4 deletions(-)
 create mode 100644 drivers/media/video/v4l2-event.c
 create mode 100644 include/media/v4l2-event.h

diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index 1947146..dd6a853 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -10,7 +10,8 @@ stkwebcam-objs:=  stk-webcam.o stk-sensor.o
 
 omap2cam-objs  :=  omap24xxcam.o omap24xxcam-dma.o
 
-videodev-objs  :=  v4l2-dev.o v4l2-ioctl.o v4l2-device.o v4l2-fh.o
+videodev-objs  :=  v4l2-dev.o v4l2-ioctl.o v4l2-device.o v4l2-fh.o \
+   v4l2-event.o
 
 # V4L2 core modules
 
diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c
index 15b2ac8..6d25297 100644
--- a/drivers/media/video/v4l2-dev.c
+++ b/drivers/media/video/v4l2-dev.c
@@ -613,22 +613,36 @@ static int __init videodev_init(void)
dev_t dev = MKDEV(VIDEO_MAJOR, 0);
int ret;
 
+   ret = v4l2_event_init();
+   if (ret  0) {
+   printk(KERN_WARNING videodev: unable to initialise events\n);
+   return ret;
+   }
+
printk(KERN_INFO Linux video capture interface: v2.00\n);
ret = register_chrdev_region(dev, VIDEO_NUM_DEVICES, VIDEO_NAME);
if (ret  0) {
printk(KERN_WARNING videodev: unable to get major %d\n,
VIDEO_MAJOR);
-   return ret;
+   goto out_register_chrdev_region;
}
 
ret = class_register(video_class);
if (ret  0) {
-   unregister_chrdev_region(dev, VIDEO_NUM_DEVICES);
printk(KERN_WARNING video_dev: class_register failed\n);
-   return -EIO;
+   ret = -EIO;
+   goto out_class_register;
}
 
return 0;
+
+out_class_register:
+   unregister_chrdev_region(dev, VIDEO_NUM_DEVICES);
+
+out_register_chrdev_region:
+   v4l2_event_exit();
+
+   return ret;
 }
 
 static void __exit videodev_exit(void)
@@ -637,6 +651,7 @@ static void __exit videodev_exit(void)
 
class_unregister(video_class);
unregister_chrdev_region(dev, VIDEO_NUM_DEVICES);
+   v4l2_event_exit();
 }
 
 module_init(videodev_init)
diff --git a/drivers/media/video/v4l2-event.c b/drivers/media/video/v4l2-event.c
new file mode 100644
index 000..9fc0c81
--- /dev/null
+++ b/drivers/media/video/v4l2-event.c
@@ -0,0 +1,254 @@
+/*
+ * drivers/media/video/v4l2-event.c
+ *
+ * V4L2 events.
+ *
+ * Copyright (C) 2009 Nokia Corporation.
+ *
+ * Contact: Sakari Ailus sakari.ai...@maxwell.research.nokia.com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#include media/v4l2-dev.h
+#include media/v4l2-event.h
+
+#include linux/sched.h
+
+static struct kmem_cache *event_kmem;
+
+int v4l2_event_init(void)
+{
+   event_kmem = kmem_cache_create(event_kmem,
+  sizeof(struct _v4l2_event), 0,
+  SLAB_HWCACHE_ALIGN,
+  NULL);
+
+   if (!event_kmem)
+   return -ENOMEM;
+
+   return 0;
+}
+
+void v4l2_event_exit(void)
+{
+   kmem_cache_destroy(event_kmem);
+}
+
+void v4l2_event_init_fh(struct v4l2_fh *fh)
+{
+   struct v4l2_events *events = fh-events;
+
+   init_waitqueue_head(events-wait);
+   spin_lock_init(events-lock);
+
+   INIT_LIST_HEAD(events-available);
+   INIT_LIST_HEAD(events-subscribed);
+}
+EXPORT_SYMBOL_GPL(v4l2_event_init_fh);
+
+void v4l2_event_exit_fh(struct v4l2_fh *fh)
+{
+   struct v4l2_events *events = fh-events;
+
+   while (!list_empty(events-available)) {
+   struct _v4l2_event *ev;
+
+  

Re: [RFC v2 4/7] V4L: Events: Add backend

2009-12-22 Thread Andy Walls
On Tue, 2009-12-22 at 18:43 +0200, Sakari Ailus wrote:
 Add event handling backend to V4L2. The backend handles event subscription
 and delivery to file handles. Event subscriptions are based on file handle.
 Events may be delivered to all subscribed file handles on a device
 independent of where they originate from.
 
 Signed-off-by: Sakari Ailus sakari.ai...@maxwell.research.nokia.com
 ---
  drivers/media/video/Makefile |3 +-
  drivers/media/video/v4l2-dev.c   |   21 +++-
  drivers/media/video/v4l2-event.c |  254 
 ++
  drivers/media/video/v4l2-fh.c|4 +
  include/media/v4l2-event.h   |   65 ++
  include/media/v4l2-fh.h  |3 +
  6 files changed, 346 insertions(+), 4 deletions(-)
  create mode 100644 drivers/media/video/v4l2-event.c
  create mode 100644 include/media/v4l2-event.h
 
 diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
 index 1947146..dd6a853 100644
 --- a/drivers/media/video/Makefile
 +++ b/drivers/media/video/Makefile
 @@ -10,7 +10,8 @@ stkwebcam-objs  :=  stk-webcam.o stk-sensor.o
  
  omap2cam-objs:=  omap24xxcam.o omap24xxcam-dma.o
  
 -videodev-objs:=  v4l2-dev.o v4l2-ioctl.o v4l2-device.o v4l2-fh.o
 +videodev-objs:=  v4l2-dev.o v4l2-ioctl.o v4l2-device.o v4l2-fh.o 
 \
 + v4l2-event.o
  
  # V4L2 core modules
  
 diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c
 index 15b2ac8..6d25297 100644
 --- a/drivers/media/video/v4l2-dev.c
 +++ b/drivers/media/video/v4l2-dev.c
 @@ -613,22 +613,36 @@ static int __init videodev_init(void)
   dev_t dev = MKDEV(VIDEO_MAJOR, 0);
   int ret;
  
 + ret = v4l2_event_init();
 + if (ret  0) {
 + printk(KERN_WARNING videodev: unable to initialise events\n);
 + return ret;
 + }
 +
   printk(KERN_INFO Linux video capture interface: v2.00\n);
   ret = register_chrdev_region(dev, VIDEO_NUM_DEVICES, VIDEO_NAME);
   if (ret  0) {
   printk(KERN_WARNING videodev: unable to get major %d\n,
   VIDEO_MAJOR);
 - return ret;
 + goto out_register_chrdev_region;
   }
  
   ret = class_register(video_class);
   if (ret  0) {
 - unregister_chrdev_region(dev, VIDEO_NUM_DEVICES);
   printk(KERN_WARNING video_dev: class_register failed\n);
 - return -EIO;
 + ret = -EIO;
 + goto out_class_register;
   }
  
   return 0;
 +
 +out_class_register:
 + unregister_chrdev_region(dev, VIDEO_NUM_DEVICES);
 +
 +out_register_chrdev_region:
 + v4l2_event_exit();
 +
 + return ret;
  }
  
  static void __exit videodev_exit(void)
 @@ -637,6 +651,7 @@ static void __exit videodev_exit(void)
  
   class_unregister(video_class);
   unregister_chrdev_region(dev, VIDEO_NUM_DEVICES);
 + v4l2_event_exit();
  }
  
  module_init(videodev_init)
 diff --git a/drivers/media/video/v4l2-event.c 
 b/drivers/media/video/v4l2-event.c
 new file mode 100644
 index 000..9fc0c81
 --- /dev/null
 +++ b/drivers/media/video/v4l2-event.c
 @@ -0,0 +1,254 @@
 +/*
 + * drivers/media/video/v4l2-event.c
 + *
 + * V4L2 events.
 + *
 + * Copyright (C) 2009 Nokia Corporation.
 + *
 + * Contact: Sakari Ailus sakari.ai...@maxwell.research.nokia.com
 + *
 + * This program is free software; you can redistribute it and/or
 + * modify it under the terms of the GNU General Public License
 + * version 2 as published by the Free Software Foundation.
 + *
 + * This program is distributed in the hope that it will be useful, but
 + * WITHOUT ANY WARRANTY; without even the implied warranty of
 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 + * General Public License for more details.
 + *
 + * You should have received a copy of the GNU General Public License
 + * along with this program; if not, write to the Free Software
 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 + * 02110-1301 USA
 + */
 +
 +#include media/v4l2-dev.h
 +#include media/v4l2-event.h
 +
 +#include linux/sched.h
 +
 +static struct kmem_cache *event_kmem;
 +
 +int v4l2_event_init(void)
 +{
 + event_kmem = kmem_cache_create(event_kmem,
 +sizeof(struct _v4l2_event), 0,
 +SLAB_HWCACHE_ALIGN,
 +NULL);
 +
 + if (!event_kmem)
 + return -ENOMEM;
 +
 + return 0;
 +}
 +
 +void v4l2_event_exit(void)
 +{
 + kmem_cache_destroy(event_kmem);
 +}
 +
 +void v4l2_event_init_fh(struct v4l2_fh *fh)
 +{
 + struct v4l2_events *events = fh-events;
 +
 + init_waitqueue_head(events-wait);
 + spin_lock_init(events-lock);
 +
 + INIT_LIST_HEAD(events-available);
 + INIT_LIST_HEAD(events-subscribed);
 +}
 +EXPORT_SYMBOL_GPL(v4l2_event_init_fh);
 +
 +void v4l2_event_exit_fh(struct v4l2_fh *fh)
 +{