From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga07.intel.com (mga07.intel.com [134.134.136.100]) by dpdk.org (Postfix) with ESMTP id 0F79B7CFC for ; Wed, 6 Dec 2017 03:52:11 +0100 (CET) Received: from orsmga006.jf.intel.com ([10.7.209.51]) by orsmga105.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 05 Dec 2017 18:52:10 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.45,366,1508828400"; d="scan'208";a="489733" Received: from tanjianf-mobl.ccr.corp.intel.com (HELO [10.67.64.58]) ([10.67.64.58]) by orsmga006.jf.intel.com with ESMTP; 05 Dec 2017 18:52:09 -0800 To: Thomas Monjalon References: <20171201003642.19827-1-thomas@monjalon.net> Cc: dev@dpdk.org From: "Tan, Jianfeng" Message-ID: Date: Wed, 6 Dec 2017 10:52:08 +0800 User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:45.0) Gecko/20100101 Thunderbird/45.8.0 MIME-Version: 1.0 In-Reply-To: <20171201003642.19827-1-thomas@monjalon.net> Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: 7bit Subject: Re: [dpdk-dev] [PATCH] bus/vdev: add custom scan hook X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 06 Dec 2017 02:52:12 -0000 On 12/1/2017 8:36 AM, Thomas Monjalon wrote: > The scan callback allows to spawn a vdev automatically > given some custom scan rules. > It is especially useful to create a TAP device automatically > connected to a netdevice as remote. > > Signed-off-by: Thomas Monjalon > --- > warning: to be tested > --- > drivers/bus/vdev/rte_bus_vdev.h | 29 ++++++++++++++++ > drivers/bus/vdev/vdev.c | 75 +++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 104 insertions(+) > > diff --git a/drivers/bus/vdev/rte_bus_vdev.h b/drivers/bus/vdev/rte_bus_vdev.h > index 41762b853..a90382f49 100644 > --- a/drivers/bus/vdev/rte_bus_vdev.h > +++ b/drivers/bus/vdev/rte_bus_vdev.h > @@ -124,6 +124,35 @@ RTE_PMD_EXPORT_NAME(nm, __COUNTER__) > #define RTE_PMD_REGISTER_ALIAS(nm, alias)\ > static const char *vdrvinit_ ## nm ## _alias = RTE_STR(alias) > > +typedef void (*rte_vdev_scan_callback)(void *user_arg); > + > +/** > + * Add a callback to be called on vdev scan > + * before reading the devargs list. > + * > + * @param callback > + * The function to be called which can update the devargs list. > + * @param user_arg > + * An opaque pointer passed to callback. > + * @return > + * 0 on success, -ENOMEM otherwise > + */ > +int > +rte_vdev_add_custom_scan(rte_vdev_scan_callback callback, void *user_arg); > + > +/** > + * Remove a registered scan callback. > + * > + * @param callback > + * The registered function to be removed. > + * @param user_arg > + * The associated opaque pointer or (void*)-1 for any. > + * @return > + * 0 on success > + */ > +int > +rte_vdev_remove_custom_scan(rte_vdev_scan_callback callback, void *user_arg); > + > /** > * Initialize a driver specified by name. > * > diff --git a/drivers/bus/vdev/vdev.c b/drivers/bus/vdev/vdev.c > index fd7736d63..902f1e128 100644 > --- a/drivers/bus/vdev/vdev.c > +++ b/drivers/bus/vdev/vdev.c > @@ -44,6 +44,8 @@ > #include > #include > #include > +#include > +#include > #include > > #include "rte_bus_vdev.h" > @@ -62,6 +64,16 @@ static struct vdev_device_list vdev_device_list = > struct vdev_driver_list vdev_driver_list = > TAILQ_HEAD_INITIALIZER(vdev_driver_list); > > +struct vdev_custom_scan { > + TAILQ_ENTRY(vdev_custom_scan) next; > + rte_vdev_scan_callback callback; > + void *user_arg; > +}; > +TAILQ_HEAD(vdev_custom_scans, vdev_custom_scan); > +static struct vdev_custom_scans vdev_custom_scans = > + TAILQ_HEAD_INITIALIZER(vdev_custom_scans); > +static rte_spinlock_t vdev_custom_scan_lock = RTE_SPINLOCK_INITIALIZER; > + > /* register a driver */ > void > rte_vdev_register(struct rte_vdev_driver *driver) > @@ -76,6 +88,53 @@ rte_vdev_unregister(struct rte_vdev_driver *driver) > TAILQ_REMOVE(&vdev_driver_list, driver, next); > } > > +int > +rte_vdev_add_custom_scan(rte_vdev_scan_callback callback, void *user_arg) > +{ > + struct vdev_custom_scan *custom_scan; > + > + rte_spinlock_lock(&vdev_custom_scan_lock); > + > + /* check if already registered */ > + TAILQ_FOREACH(custom_scan, &vdev_custom_scans, next) { > + if (custom_scan->callback == callback && > + custom_scan->user_arg == user_arg) > + break; > + } > + > + if (custom_scan == NULL) { > + custom_scan = malloc(sizeof(struct vdev_custom_scan)); > + if (custom_scan != NULL) { > + custom_scan->callback = callback; > + custom_scan->user_arg = user_arg; > + TAILQ_INSERT_TAIL(&vdev_custom_scans, custom_scan, next); > + } > + } > + > + rte_spinlock_unlock(&vdev_custom_scan_lock); > + > + return (custom_scan == NULL) ? -ENOMEM : 0; > +} > + > +int > +rte_vdev_remove_custom_scan(rte_vdev_scan_callback callback, void *user_arg) > +{ > + struct vdev_custom_scan *custom_scan, *tmp_scan; > + > + rte_spinlock_lock(&vdev_custom_scan_lock); > + TAILQ_FOREACH_SAFE(custom_scan, &vdev_custom_scans, next, tmp_scan) { > + if (custom_scan->callback != callback || > + (custom_scan->user_arg != (void *)-1 && > + custom_scan->user_arg != user_arg)) > + continue; > + TAILQ_REMOVE(&vdev_custom_scans, custom_scan, next); > + free(custom_scan); > + } > + rte_spinlock_unlock(&vdev_custom_scan_lock); > + > + return 0; > +} > + > static int > vdev_parse(const char *name, void *addr) > { > @@ -260,6 +319,22 @@ vdev_scan(void) > { > struct rte_vdev_device *dev; > struct rte_devargs *devargs; > + struct vdev_custom_scan *custom_scan; > + > + /* call custom scan callbacks if any */ > + rte_spinlock_lock(&vdev_custom_scan_lock); > + TAILQ_FOREACH(custom_scan, &vdev_custom_scans, next) { > + if (custom_scan->callback != NULL) > + /* > + * the callback should update devargs list > + * by calling rte_eal_devargs_insert() with > + * devargs.bus = rte_bus_find_by_name("vdev"); > + * devargs.type = RTE_DEVTYPE_VIRTUAL; > + * devargs.policy = RTE_DEV_WHITELISTED; > + */ > + custom_scan->callback(custom_scan->user_arg); > + } > + rte_spinlock_unlock(&vdev_custom_scan_lock); You mentioned that we want to call the hook in the scan(), but it's now in parse()? Thanks, Jianfeng > > /* for virtual devices we scan the devargs_list populated via cmdline */ > TAILQ_FOREACH(devargs, &devargs_list, next) {