From mboxrd@z Thu Jan 1 00:00:00 1970 From: "Wu, Jingjing" Subject: Re: [PATCH V12 1/3] eal: add uevent monitor api and callback func Date: Wed, 24 Jan 2018 14:52:47 +0000 Message-ID: <9BB6961774997848B5B42BEC655768F810F17FAB@SHSMSX103.ccr.corp.intel.com> References: <1516013331-18939-3-git-send-email-jia.guo@intel.com> <1516248723-16985-1-git-send-email-jia.guo@intel.com> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Cc: "Ananyev, Konstantin" , "jblunck@infradead.org" , "shreyansh.jain@nxp.com" , "dev@dpdk.org" , "thomas@monjalon.net" , "Zhang, Helin" , "motih@mellanox.com" To: "Guo, Jia" , "stephen@networkplumber.org" , "Richardson, Bruce" , "Yigit, Ferruh" , "gaetan.rivet@6wind.com" Return-path: Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by dpdk.org (Postfix) with ESMTP id BA8211B1A5 for ; Wed, 24 Jan 2018 15:52:51 +0100 (CET) In-Reply-To: <1516248723-16985-1-git-send-email-jia.guo@intel.com> Content-Language: en-US List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" > -----Original Message----- > From: Guo, Jia > Sent: Thursday, January 18, 2018 12:12 PM > To: stephen@networkplumber.org; Richardson, Bruce ; > Yigit, Ferruh ; gaetan.rivet@6wind.com > Cc: Ananyev, Konstantin ; jblunck@infradead= .org; > shreyansh.jain@nxp.com; Wu, Jingjing ; dev@dpdk.or= g; Guo, Jia > ; thomas@monjalon.net; Zhang, Helin ; > motih@mellanox.com > Subject: [PATCH V12 1/3] eal: add uevent monitor api and callback func >=20 > This patch aim to add a general uevent mechanism in eal device layer, > to enable all linux kernel object uevent monitoring, user could use these > APIs to monitor and read out the device status info that sent from the > kernel side, then corresponding to handle it, such as when detect hotplug > uevent type, user could detach or attach the device, and more it benefit > to use to do smoothly fail safe work. >=20 > About uevent monitoring: > a: add one epolling to poll the netlink socket, to monitor the uevent of > the device. > b: add enum of rte_eal_dev_event_type and struct of rte_eal_uevent. > c: add below APIs in rte eal device layer. > rte_dev_callback_register > rte_dev_callback_unregister > _rte_dev_callback_process > rte_dev_event_monitor_start > rte_dev_event_monitor_stop >=20 > Signed-off-by: Jeff Guo > --- > v12->v11: > identify null param in callback for monitor all devices uevent > --- > lib/librte_eal/bsdapp/eal/eal_dev.c | 38 ++++++ > lib/librte_eal/common/eal_common_dev.c | 128 ++++++++++++++++++ > lib/librte_eal/common/include/rte_dev.h | 119 +++++++++++++++++ > lib/librte_eal/linuxapp/eal/Makefile | 1 + > lib/librte_eal/linuxapp/eal/eal_dev.c | 223 ++++++++++++++++++++++++++= ++++++ > 5 files changed, 509 insertions(+) > create mode 100644 lib/librte_eal/bsdapp/eal/eal_dev.c > create mode 100644 lib/librte_eal/linuxapp/eal/eal_dev.c >=20 [......] > +int > +rte_dev_callback_register(char *device_name, rte_dev_event_cb_fn cb_fn, > + void *cb_arg) > +{ > + struct rte_dev_event_callback *event_cb =3D NULL; > + > + rte_spinlock_lock(&rte_dev_event_lock); > + > + if (TAILQ_EMPTY(&(dev_event_cbs))) > + TAILQ_INIT(&(dev_event_cbs)); > + > + TAILQ_FOREACH(event_cb, &(dev_event_cbs), next) { > + if (event_cb->cb_fn =3D=3D cb_fn && > + event_cb->cb_arg =3D=3D cb_arg && > + !strcmp(event_cb->dev_name, device_name)) device_name =3D NULL means means for all devices, right? Can strcmp accept = NULL arguments? > + break; > + } > + > + /* create a new callback. */ > + if (event_cb =3D=3D NULL) { > + /* allocate a new user callback entity */ > + event_cb =3D malloc(sizeof(struct rte_dev_event_callback)); > + if (event_cb !=3D NULL) { > + event_cb->cb_fn =3D cb_fn; > + event_cb->cb_arg =3D cb_arg; > + event_cb->dev_name =3D device_name; > + } Is that OK to call TAILQ_INSERT_TAIL below if event_cb =3D=3D NULL? > + TAILQ_INSERT_TAIL(&(dev_event_cbs), event_cb, next); > + } > + > + rte_spinlock_unlock(&rte_dev_event_lock); > + return (event_cb =3D=3D NULL) ? -1 : 0; > +} > + > +int > +rte_dev_callback_unregister(char *device_name, rte_dev_event_cb_fn cb_fn= , > + void *cb_arg) > +{ > + int ret; > + struct rte_dev_event_callback *event_cb, *next; > + > + if (!cb_fn || device_name =3D=3D NULL) > + return -EINVAL; > + > + rte_spinlock_lock(&rte_dev_event_lock); > + > + ret =3D 0; > + > + for (event_cb =3D TAILQ_FIRST(&(dev_event_cbs)); event_cb !=3D NULL; > + event_cb =3D next) { > + > + next =3D TAILQ_NEXT(event_cb, next); > + > + if (event_cb->cb_fn !=3D cb_fn || > + (event_cb->cb_arg !=3D (void *)-1 && > + event_cb->cb_arg !=3D cb_arg) || > + strcmp(event_cb->dev_name, device_name)) The same comments as above. > + continue; > + > + /* > + * if this callback is not executing right now, > + * then remove it. > + */ > + if (event_cb->active =3D=3D 0) { > + TAILQ_REMOVE(&(dev_event_cbs), event_cb, next); > + rte_free(event_cb); > + } else { > + ret =3D -EAGAIN; > + } > + } > + > + rte_spinlock_unlock(&rte_dev_event_lock); > + return ret; > +} > + [......] > +int > +rte_dev_event_monitor_start(void) > +{ > + int ret; > + struct rte_service_spec service; > + uint32_t id; > + const uint32_t sid =3D 0; > + > + if (!service_no_init) > + return 0; > + > + uint32_t slcore_1 =3D rte_get_next_lcore(/* start core */ -1, > + /* skip master */ 1, > + /* wrap */ 0); > + > + ret =3D rte_service_lcore_add(slcore_1); > + if (ret) { > + RTE_LOG(ERR, EAL, "dev event monitor lcore add fail"); > + return ret; > + } > + > + memset(&service, 0, sizeof(service)); > + snprintf(service.name, sizeof(service.name), DEV_EV_MNT_SERVICE_NAME); > + > + service.socket_id =3D rte_socket_id(); > + service.callback =3D dev_uev_monitoring; > + service.callback_userdata =3D NULL; > + service.capabilities =3D 0; > + ret =3D rte_service_component_register(&service, &id); > + if (ret) { > + RTE_LOG(ERR, EAL, "Failed to register service %s " > + "err =3D %" PRId32, > + service.name, ret); > + return ret; > + } > + ret =3D rte_service_runstate_set(sid, 1); > + if (ret) { > + RTE_LOG(ERR, EAL, "Failed to set the runstate of " > + "the service"); Any rollback need to be done when fails? > + return ret; > + } > + ret =3D rte_service_component_runstate_set(id, 1); > + if (ret) { > + RTE_LOG(ERR, EAL, "Failed to set the backend runstate" > + " of a component"); > + return ret; > + } > + ret =3D rte_service_map_lcore_set(sid, slcore_1, 1); > + if (ret) { > + RTE_LOG(ERR, EAL, "Failed to enable lcore 1 on " > + "dev event monitor service"); > + return ret; > + } > + rte_service_lcore_start(slcore_1); > + service_no_init =3D false; > + return 0; > +} > + > +int > +rte_dev_event_monitor_stop(void) > +{ > + service_exit =3D true; > + service_no_init =3D true; > + return 0; Are start and stop peer functions to call? If we call rte_dev_event_monitor= _start to start monitor and then call rte_dev_event_monitor_stop to stop it= , and then how to start again? > +} > -- > 2.7.4