From: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
To: Shuah Khan <shuahkh@osg.samsung.com>
Cc: laurent.pinchart@ideasonboard.com, perex@perex.cz,
tiwai@suse.com, hans.verkuil@cisco.com, chehabrafael@gmail.com,
javier@osg.samsung.com, jh1009.sung@samsung.com,
linux-kernel@vger.kernel.org, linux-media@vger.kernel.org,
alsa-devel@alsa-project.org
Subject: Re: [RFC PATCH 1/4] media: Add Media Device Allocator API
Date: Mon, 28 Mar 2016 15:28:31 -0300 [thread overview]
Message-ID: <20160328152831.6f2ef88d@recife.lan> (raw)
In-Reply-To: <41d017ef76e3206780c018399ec60b63d865f65c.1458966594.git.shuahkh@osg.samsung.com>
Hi Shuah,
I reviewed the entire patch series, but I'm adding the comments only here,
as the other patches are coherent with this one.
Em Fri, 25 Mar 2016 22:38:42 -0600
Shuah Khan <shuahkh@osg.samsung.com> escreveu:
> Add Media Device Allocator API to manage Media Device life time problems.
> There are known problems with media device life time management. When media
> device is released while an media ioctl is in progress, ioctls fail with
> use-after-free errors and kernel hangs in some cases.
>
> Media Allocator API provides interfaces to allocate a refcounted media
> device from system wide global list and maintains the state until the
> last user of the media device releases it.
>
> Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
> ---
> drivers/media/Makefile | 3 +-
> drivers/media/media-dev-allocator.c | 153 ++++++++++++++++++++++++++++++++++++
> include/media/media-dev-allocator.h | 81 +++++++++++++++++++
> 3 files changed, 236 insertions(+), 1 deletion(-)
> create mode 100644 drivers/media/media-dev-allocator.c
> create mode 100644 include/media/media-dev-allocator.h
>
> diff --git a/drivers/media/Makefile b/drivers/media/Makefile
> index e608bbc..b08f091 100644
> --- a/drivers/media/Makefile
> +++ b/drivers/media/Makefile
> @@ -2,7 +2,8 @@
> # Makefile for the kernel multimedia device drivers.
> #
>
> -media-objs := media-device.o media-devnode.o media-entity.o
> +media-objs := media-device.o media-devnode.o media-entity.o \
> + media-dev-allocator.o
>
> #
> # I2C drivers should come before other drivers, otherwise they'll fail
> diff --git a/drivers/media/media-dev-allocator.c b/drivers/media/media-dev-allocator.c
> new file mode 100644
> index 0000000..51edc49
> --- /dev/null
> +++ b/drivers/media/media-dev-allocator.c
> @@ -0,0 +1,153 @@
> +/*
> + * media-devkref.c - Media Controller Device Allocator API
> + *
> + * Copyright (c) 2016 Shuah Khan <shuahkh@osg.samsung.com>
> + * Copyright (c) 2016 Samsung Electronics Co., Ltd.
> + *
> + * This file is released under the GPLv2.
> + * Credits: Suggested by Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> + */
> +
> +/*
> + * This file adds Media Controller Device Instance with
> + * Kref support. A system wide global media device list
> + * is managed and each media device is refcounted. The
> + * last put on the media device releases the media device
> + * instance.
> +*/
> +
> +#ifdef CONFIG_MEDIA_CONTROLLER
No need for an ifdef here. This file will be compiled only
if CONFIG_MEDIA_CONTROLLER, as you added it for media.ko
dependencies at the Makefile.
> +
> +#include <linux/slab.h>
> +#include <linux/kref.h>
> +#include <media/media-device.h>
> +
> +static LIST_HEAD(media_device_list);
> +static LIST_HEAD(media_device_to_delete_list);
> +static DEFINE_MUTEX(media_device_lock);
> +
> +struct media_device_instance {
> + struct media_device mdev;
> + struct list_head list;
> + struct list_head to_delete_list;
> + struct device *dev;
> + struct kref refcount;
> + bool to_delete; /* should be set when devnode is deleted */
I don't think this is needed.
> +};
> +
> +static struct media_device *__media_device_get(struct device *dev,
> + bool alloc, bool kref)
> +{
Please don't use "kref" for a boolean here. Makes it confusing, as reviewers
would expect "kref" to be of "struct kref" type.
Also, alloc seems to be a bad name for the other bool.
Maybe you could call them as "do_alloc" and "create_kref".
> + struct media_device_instance *mdi;
> +
> + mutex_lock(&media_device_lock);
> +
> + list_for_each_entry(mdi, &media_device_list, list) {
> + if (mdi->dev == dev) {
> + if (kref) {
> + kref_get(&mdi->refcount);
> + pr_info("%s: mdev=%p\n", __func__, &mdi->mdev);
> + }
> + goto done;
> + }
> + }
> +
> + if (!alloc) {
> + mdi = NULL;
> + goto done;
> + }
> +
> + mdi = kzalloc(sizeof(*mdi), GFP_KERNEL);
> + if (!mdi)
> + goto done;
> +
> + mdi->dev = dev;
> + kref_init(&mdi->refcount);
> + list_add_tail(&mdi->list, &media_device_list);
> + pr_info("%s: mdev=%p\n", __func__, &mdi->mdev);
> +
> +done:
> + mutex_unlock(&media_device_lock);
> +
> + return mdi ? &mdi->mdev : NULL;
> +}
> +
> +struct media_device *media_device_get(struct device *dev)
> +{
> + pr_info("%s\n", __func__);
> + return __media_device_get(dev, true, true);
> +}
> +EXPORT_SYMBOL_GPL(media_device_get);
> +
> +/* Don't increment kref - this is a search and find */
> +struct media_device *media_device_find(struct device *dev)
> +{
> + pr_info("%s\n", __func__);
> + return __media_device_get(dev, false, false);
> +}
> +EXPORT_SYMBOL_GPL(media_device_find);
> +
> +/* don't allocate - increment kref if one is found */
> +struct media_device *media_device_get_ref(struct device *dev)
> +{
> + pr_info("%s\n", __func__);
> + return __media_device_get(dev, false, true);
> +}
> +EXPORT_SYMBOL_GPL(media_device_get_ref);
> +
> +static void media_device_instance_release(struct kref *kref)
> +{
> + struct media_device_instance *mdi =
> + container_of(kref, struct media_device_instance, refcount);
> +
> + pr_info("%s: mdev=%p\n", __func__, &mdi->mdev);
> +
> + list_del(&mdi->list);
> + kfree(mdi);
> +}
> +
> +void media_device_put(struct device *dev)
> +{
> + struct media_device_instance *mdi;
> +
> + mutex_lock(&media_device_lock);
> + /* search first in the media_device_list */
> + list_for_each_entry(mdi, &media_device_list, list) {
> + if (mdi->dev == dev) {
> + pr_info("%s: mdev=%p\n", __func__, &mdi->mdev);
> + kref_put(&mdi->refcount, media_device_instance_release);
> + goto done;
> + }
> + }
> + /* search in the media_device_to_delete_list */
> + list_for_each_entry(mdi, &media_device_to_delete_list, to_delete_list) {
> + if (mdi->dev == dev) {
> + pr_info("%s: mdev=%p\n", __func__, &mdi->mdev);
> + kref_put(&mdi->refcount, media_device_instance_release);
> + goto done;
> + }
> + }
> +done:
> + mutex_unlock(&media_device_lock);
> +}
> +EXPORT_SYMBOL_GPL(media_device_put);
You also need something to initialize the kref for places where
the struct media_device is embedded, or to convert all of them to use
dynamically-allocated media_device structs.
> +
> +void media_device_set_to_delete_state(struct device *dev)
> +{
> + struct media_device_instance *mdi;
> +
> + mutex_lock(&media_device_lock);
> + list_for_each_entry(mdi, &media_device_list, list) {
> + if (mdi->dev == dev) {
> + pr_info("%s: mdev=%p\n", __func__, &mdi->mdev);
> + mdi->to_delete = true;
> + list_move(&mdi->list, &media_device_to_delete_list);
> + goto done;
> + }
> + }
> +done:
> + mutex_unlock(&media_device_lock);
> +}
> +EXPORT_SYMBOL_GPL(media_device_set_to_delete_state);
> +
> +#endif /* CONFIG_MEDIA_CONTROLLER */
> diff --git a/include/media/media-dev-allocator.h b/include/media/media-dev-allocator.h
> new file mode 100644
> index 0000000..2932c90
> --- /dev/null
> +++ b/include/media/media-dev-allocator.h
> @@ -0,0 +1,81 @@
> +/*
> + * media-devkref.c - Media Controller Device Allocator API
> + *
> + * Copyright (c) 2016 Shuah Khan <shuahkh@osg.samsung.com>
> + * Copyright (c) 2016 Samsung Electronics Co., Ltd.
> + *
> + * This file is released under the GPLv2.
> + * Credits: Suggested by Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> + */
> +
> +/*
> + * This file adds Media Controller Device Instance with Kref support.
> + * A system wide global media device list is managed and each media
> + * device is refcounted. The last put on the media device releases
> + * the media device instance.
> +*/
> +
> +#ifndef _MEDIA_DEV_ALLOCTOR_H
> +#define _MEDIA_DEV_ALLOCTOR_H
> +
> +#ifdef CONFIG_MEDIA_CONTROLLER
> +/**
> + * media_device_get() - Allocate and return global media device
> + *
> + * @mdev
> + *
> + * This interface should be called to allocate media device. A new media
> + * device instance is created and added to the system wide media device
> + * instance list. If media device instance exists, media_device_get()
> + * increments the reference count and returns the media device. When
> + * more than one driver control the media device, the first driver to
> + * probe will allocate and the second driver when it calls media_device_get()
> + * it will get a reference.
> + *
> + */
> +struct media_device *media_device_get(struct device *dev);
> +/**
> + * media_device_get_ref() - Get reference to an allocated and registered
> + * media device.
> + *
> + * @mdev
> + *
> + * This interface should be called to get a reference to an allocated media
> + * device. media_open() ioctl should call this to hold a reference to ensure
> + * the media device will not be released until the media_release() does a put
> + * on it.
> + */
> +struct media_device *media_device_get_ref(struct device *dev);
> +/**
> + * media_device_find() - Find an allocated and registered media device.
> + *
> + * @mdev
> + *
> + * This interface should be called to find a media device. This will not
> + * incremnet the reference count.
> + */
> +struct media_device *media_device_find(struct device *dev);
> +/**
> + * media_device_put() - Release refcounted media device. Calls kref_put()
> + *
> + * @mdev
> + *
> + * This interface should be called to decrement refcount.
> + */
> +void media_device_put(struct device *dev);
> +/**
> + * media_device_set_to_delete_state() - Set the state to be deleted.
> + *
> + * @mdev
> + *
> + * This interface is used to not release the media device under from
> + * an active ioctl if unregister happens.
> + */
> +void media_device_set_to_delete_state(struct device *dev);
> +#else
> +struct media_device *media_device_get(struct device *dev) { return NULL; }
> +struct media_device *media_device_find(struct device *dev) { return NULL; }
> +void media_device_put(struct media_device *mdev) { }
> +void media_device_set_to_delete_state(struct device *dev) { }
> +#endif /* CONFIG_MEDIA_CONTROLLER */
> +#endif
--
Thanks,
Mauro
WARNING: multiple messages have this Message-ID (diff)
From: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
To: Shuah Khan <shuahkh@osg.samsung.com>
Cc: <laurent.pinchart@ideasonboard.com>, <perex@perex.cz>,
<tiwai@suse.com>, <hans.verkuil@cisco.com>,
<chehabrafael@gmail.com>, <javier@osg.samsung.com>,
<jh1009.sung@samsung.com>, <linux-kernel@vger.kernel.org>,
<linux-media@vger.kernel.org>, <alsa-devel@alsa-project.org>
Subject: Re: [RFC PATCH 1/4] media: Add Media Device Allocator API
Date: Mon, 28 Mar 2016 15:28:31 -0300 [thread overview]
Message-ID: <20160328152831.6f2ef88d@recife.lan> (raw)
In-Reply-To: <41d017ef76e3206780c018399ec60b63d865f65c.1458966594.git.shuahkh@osg.samsung.com>
Hi Shuah,
I reviewed the entire patch series, but I'm adding the comments only here,
as the other patches are coherent with this one.
Em Fri, 25 Mar 2016 22:38:42 -0600
Shuah Khan <shuahkh@osg.samsung.com> escreveu:
> Add Media Device Allocator API to manage Media Device life time problems.
> There are known problems with media device life time management. When media
> device is released while an media ioctl is in progress, ioctls fail with
> use-after-free errors and kernel hangs in some cases.
>
> Media Allocator API provides interfaces to allocate a refcounted media
> device from system wide global list and maintains the state until the
> last user of the media device releases it.
>
> Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
> ---
> drivers/media/Makefile | 3 +-
> drivers/media/media-dev-allocator.c | 153 ++++++++++++++++++++++++++++++++++++
> include/media/media-dev-allocator.h | 81 +++++++++++++++++++
> 3 files changed, 236 insertions(+), 1 deletion(-)
> create mode 100644 drivers/media/media-dev-allocator.c
> create mode 100644 include/media/media-dev-allocator.h
>
> diff --git a/drivers/media/Makefile b/drivers/media/Makefile
> index e608bbc..b08f091 100644
> --- a/drivers/media/Makefile
> +++ b/drivers/media/Makefile
> @@ -2,7 +2,8 @@
> # Makefile for the kernel multimedia device drivers.
> #
>
> -media-objs := media-device.o media-devnode.o media-entity.o
> +media-objs := media-device.o media-devnode.o media-entity.o \
> + media-dev-allocator.o
>
> #
> # I2C drivers should come before other drivers, otherwise they'll fail
> diff --git a/drivers/media/media-dev-allocator.c b/drivers/media/media-dev-allocator.c
> new file mode 100644
> index 0000000..51edc49
> --- /dev/null
> +++ b/drivers/media/media-dev-allocator.c
> @@ -0,0 +1,153 @@
> +/*
> + * media-devkref.c - Media Controller Device Allocator API
> + *
> + * Copyright (c) 2016 Shuah Khan <shuahkh@osg.samsung.com>
> + * Copyright (c) 2016 Samsung Electronics Co., Ltd.
> + *
> + * This file is released under the GPLv2.
> + * Credits: Suggested by Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> + */
> +
> +/*
> + * This file adds Media Controller Device Instance with
> + * Kref support. A system wide global media device list
> + * is managed and each media device is refcounted. The
> + * last put on the media device releases the media device
> + * instance.
> +*/
> +
> +#ifdef CONFIG_MEDIA_CONTROLLER
No need for an ifdef here. This file will be compiled only
if CONFIG_MEDIA_CONTROLLER, as you added it for media.ko
dependencies at the Makefile.
> +
> +#include <linux/slab.h>
> +#include <linux/kref.h>
> +#include <media/media-device.h>
> +
> +static LIST_HEAD(media_device_list);
> +static LIST_HEAD(media_device_to_delete_list);
> +static DEFINE_MUTEX(media_device_lock);
> +
> +struct media_device_instance {
> + struct media_device mdev;
> + struct list_head list;
> + struct list_head to_delete_list;
> + struct device *dev;
> + struct kref refcount;
> + bool to_delete; /* should be set when devnode is deleted */
I don't think this is needed.
> +};
> +
> +static struct media_device *__media_device_get(struct device *dev,
> + bool alloc, bool kref)
> +{
Please don't use "kref" for a boolean here. Makes it confusing, as reviewers
would expect "kref" to be of "struct kref" type.
Also, alloc seems to be a bad name for the other bool.
Maybe you could call them as "do_alloc" and "create_kref".
> + struct media_device_instance *mdi;
> +
> + mutex_lock(&media_device_lock);
> +
> + list_for_each_entry(mdi, &media_device_list, list) {
> + if (mdi->dev == dev) {
> + if (kref) {
> + kref_get(&mdi->refcount);
> + pr_info("%s: mdev=%p\n", __func__, &mdi->mdev);
> + }
> + goto done;
> + }
> + }
> +
> + if (!alloc) {
> + mdi = NULL;
> + goto done;
> + }
> +
> + mdi = kzalloc(sizeof(*mdi), GFP_KERNEL);
> + if (!mdi)
> + goto done;
> +
> + mdi->dev = dev;
> + kref_init(&mdi->refcount);
> + list_add_tail(&mdi->list, &media_device_list);
> + pr_info("%s: mdev=%p\n", __func__, &mdi->mdev);
> +
> +done:
> + mutex_unlock(&media_device_lock);
> +
> + return mdi ? &mdi->mdev : NULL;
> +}
> +
> +struct media_device *media_device_get(struct device *dev)
> +{
> + pr_info("%s\n", __func__);
> + return __media_device_get(dev, true, true);
> +}
> +EXPORT_SYMBOL_GPL(media_device_get);
> +
> +/* Don't increment kref - this is a search and find */
> +struct media_device *media_device_find(struct device *dev)
> +{
> + pr_info("%s\n", __func__);
> + return __media_device_get(dev, false, false);
> +}
> +EXPORT_SYMBOL_GPL(media_device_find);
> +
> +/* don't allocate - increment kref if one is found */
> +struct media_device *media_device_get_ref(struct device *dev)
> +{
> + pr_info("%s\n", __func__);
> + return __media_device_get(dev, false, true);
> +}
> +EXPORT_SYMBOL_GPL(media_device_get_ref);
> +
> +static void media_device_instance_release(struct kref *kref)
> +{
> + struct media_device_instance *mdi =
> + container_of(kref, struct media_device_instance, refcount);
> +
> + pr_info("%s: mdev=%p\n", __func__, &mdi->mdev);
> +
> + list_del(&mdi->list);
> + kfree(mdi);
> +}
> +
> +void media_device_put(struct device *dev)
> +{
> + struct media_device_instance *mdi;
> +
> + mutex_lock(&media_device_lock);
> + /* search first in the media_device_list */
> + list_for_each_entry(mdi, &media_device_list, list) {
> + if (mdi->dev == dev) {
> + pr_info("%s: mdev=%p\n", __func__, &mdi->mdev);
> + kref_put(&mdi->refcount, media_device_instance_release);
> + goto done;
> + }
> + }
> + /* search in the media_device_to_delete_list */
> + list_for_each_entry(mdi, &media_device_to_delete_list, to_delete_list) {
> + if (mdi->dev == dev) {
> + pr_info("%s: mdev=%p\n", __func__, &mdi->mdev);
> + kref_put(&mdi->refcount, media_device_instance_release);
> + goto done;
> + }
> + }
> +done:
> + mutex_unlock(&media_device_lock);
> +}
> +EXPORT_SYMBOL_GPL(media_device_put);
You also need something to initialize the kref for places where
the struct media_device is embedded, or to convert all of them to use
dynamically-allocated media_device structs.
> +
> +void media_device_set_to_delete_state(struct device *dev)
> +{
> + struct media_device_instance *mdi;
> +
> + mutex_lock(&media_device_lock);
> + list_for_each_entry(mdi, &media_device_list, list) {
> + if (mdi->dev == dev) {
> + pr_info("%s: mdev=%p\n", __func__, &mdi->mdev);
> + mdi->to_delete = true;
> + list_move(&mdi->list, &media_device_to_delete_list);
> + goto done;
> + }
> + }
> +done:
> + mutex_unlock(&media_device_lock);
> +}
> +EXPORT_SYMBOL_GPL(media_device_set_to_delete_state);
> +
> +#endif /* CONFIG_MEDIA_CONTROLLER */
> diff --git a/include/media/media-dev-allocator.h b/include/media/media-dev-allocator.h
> new file mode 100644
> index 0000000..2932c90
> --- /dev/null
> +++ b/include/media/media-dev-allocator.h
> @@ -0,0 +1,81 @@
> +/*
> + * media-devkref.c - Media Controller Device Allocator API
> + *
> + * Copyright (c) 2016 Shuah Khan <shuahkh@osg.samsung.com>
> + * Copyright (c) 2016 Samsung Electronics Co., Ltd.
> + *
> + * This file is released under the GPLv2.
> + * Credits: Suggested by Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> + */
> +
> +/*
> + * This file adds Media Controller Device Instance with Kref support.
> + * A system wide global media device list is managed and each media
> + * device is refcounted. The last put on the media device releases
> + * the media device instance.
> +*/
> +
> +#ifndef _MEDIA_DEV_ALLOCTOR_H
> +#define _MEDIA_DEV_ALLOCTOR_H
> +
> +#ifdef CONFIG_MEDIA_CONTROLLER
> +/**
> + * media_device_get() - Allocate and return global media device
> + *
> + * @mdev
> + *
> + * This interface should be called to allocate media device. A new media
> + * device instance is created and added to the system wide media device
> + * instance list. If media device instance exists, media_device_get()
> + * increments the reference count and returns the media device. When
> + * more than one driver control the media device, the first driver to
> + * probe will allocate and the second driver when it calls media_device_get()
> + * it will get a reference.
> + *
> + */
> +struct media_device *media_device_get(struct device *dev);
> +/**
> + * media_device_get_ref() - Get reference to an allocated and registered
> + * media device.
> + *
> + * @mdev
> + *
> + * This interface should be called to get a reference to an allocated media
> + * device. media_open() ioctl should call this to hold a reference to ensure
> + * the media device will not be released until the media_release() does a put
> + * on it.
> + */
> +struct media_device *media_device_get_ref(struct device *dev);
> +/**
> + * media_device_find() - Find an allocated and registered media device.
> + *
> + * @mdev
> + *
> + * This interface should be called to find a media device. This will not
> + * incremnet the reference count.
> + */
> +struct media_device *media_device_find(struct device *dev);
> +/**
> + * media_device_put() - Release refcounted media device. Calls kref_put()
> + *
> + * @mdev
> + *
> + * This interface should be called to decrement refcount.
> + */
> +void media_device_put(struct device *dev);
> +/**
> + * media_device_set_to_delete_state() - Set the state to be deleted.
> + *
> + * @mdev
> + *
> + * This interface is used to not release the media device under from
> + * an active ioctl if unregister happens.
> + */
> +void media_device_set_to_delete_state(struct device *dev);
> +#else
> +struct media_device *media_device_get(struct device *dev) { return NULL; }
> +struct media_device *media_device_find(struct device *dev) { return NULL; }
> +void media_device_put(struct media_device *mdev) { }
> +void media_device_set_to_delete_state(struct device *dev) { }
> +#endif /* CONFIG_MEDIA_CONTROLLER */
> +#endif
--
Thanks,
Mauro
next prev parent reply other threads:[~2016-03-28 18:28 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-03-26 4:38 [RFC PATCH 0/4] Media Device Allocator API Shuah Khan
2016-03-26 4:38 ` [RFC PATCH 1/4] media: Add " Shuah Khan
2016-03-26 12:50 ` Joe Perches
2016-03-28 13:45 ` Shuah Khan
2016-03-28 18:28 ` Mauro Carvalho Chehab [this message]
2016-03-28 18:28 ` Mauro Carvalho Chehab
2016-03-28 21:34 ` Shuah Khan
2016-04-05 16:19 ` Mauro Carvalho Chehab
2016-03-26 4:38 ` [RFC PATCH 2/4] media: Add Media Device Allocator API documentation Shuah Khan
2016-03-28 18:28 ` Mauro Carvalho Chehab
2016-03-28 18:28 ` Mauro Carvalho Chehab
2016-03-28 21:14 ` Shuah Khan
2016-03-26 4:38 ` [RFC PATCH 3/4] media: Add refcount to keep track of media device registrations Shuah Khan
2016-03-28 18:28 ` Mauro Carvalho Chehab
2016-03-28 18:28 ` Mauro Carvalho Chehab
2016-03-28 21:37 ` Shuah Khan
2016-04-05 16:23 ` Mauro Carvalho Chehab
2016-04-05 16:23 ` Mauro Carvalho Chehab
2016-03-26 4:38 ` [RFC PATCH 4/4] drivers: change au0828, uvcvideo, snd-usb-audio to use Media Device Allocator Shuah Khan
2016-03-26 4:38 ` Shuah Khan
2016-03-28 18:28 ` Mauro Carvalho Chehab
2016-03-28 18:28 ` Mauro Carvalho Chehab
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20160328152831.6f2ef88d@recife.lan \
--to=mchehab@osg.samsung.com \
--cc=alsa-devel@alsa-project.org \
--cc=chehabrafael@gmail.com \
--cc=hans.verkuil@cisco.com \
--cc=javier@osg.samsung.com \
--cc=jh1009.sung@samsung.com \
--cc=laurent.pinchart@ideasonboard.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-media@vger.kernel.org \
--cc=perex@perex.cz \
--cc=shuahkh@osg.samsung.com \
--cc=tiwai@suse.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.