From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga12.intel.com (mga12.intel.com [192.55.52.136]) by dpdk.org (Postfix) with ESMTP id 42F1F7292 for ; Wed, 21 Mar 2018 06:28:45 +0100 (CET) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by fmsmga106.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 20 Mar 2018 22:28:45 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.48,338,1517904000"; d="scan'208";a="26248026" Received: from jeffguo-z170x-ud5.sh.intel.com (HELO localhost.localdomain) ([10.67.104.10]) by fmsmga008.fm.intel.com with ESMTP; 20 Mar 2018 22:28:43 -0700 From: Jeff Guo To: stephen@networkplumber.org, bruce.richardson@intel.com, ferruh.yigit@intel.com, konstantin.ananyev@intel.com, gaetan.rivet@6wind.com, jingjing.wu@intel.com, thomas@monjalon.net, motih@mellanox.com, harry.van.haaren@intel.com, jianfeng.tan@intel.com Cc: jblunck@infradead.org, shreyansh.jain@nxp.com, dev@dpdk.org, jia.guo@intel.com, helin.zhang@intel.com Date: Wed, 21 Mar 2018 13:27:45 +0800 Message-Id: <1521610066-12966-2-git-send-email-jia.guo@intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1521610066-12966-1-git-send-email-jia.guo@intel.com> References: <1517314860-8097-3-git-send-email-jia.guo@intel.com> <1521610066-12966-1-git-send-email-jia.guo@intel.com> Subject: [dpdk-dev] [PATCH V15 2/5] eal: add uevent pass and process function 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, 21 Mar 2018 05:28:46 -0000 In order to handle the uevent which have been detected from the kernel side, add uevent process function, let hot plug event to be example to show uevent mechanism how to pass the uevent and process the uevent. About uevent passing and processing, add below functions in linux eal dev layer. FreeBSD not support uevent ,so let it to be void and do not implement in function. a.dev_uev_parse b.dev_uev_receive c.dev_uev_process Signed-off-by: Jeff Guo --- v15->v14: remove the uevent type check and any policy from eal, let it check and management in user's callback. --- lib/librte_eal/common/include/rte_dev.h | 17 ++++++ lib/librte_eal/linuxapp/eal/eal_dev.c | 95 ++++++++++++++++++++++++++++++++- 2 files changed, 111 insertions(+), 1 deletion(-) diff --git a/lib/librte_eal/common/include/rte_dev.h b/lib/librte_eal/common/include/rte_dev.h index d2fcbc9..98ea12b 100644 --- a/lib/librte_eal/common/include/rte_dev.h +++ b/lib/librte_eal/common/include/rte_dev.h @@ -24,6 +24,23 @@ extern "C" { #include #include +#define RTE_EAL_UEV_MSG_LEN 4096 +#define RTE_EAL_UEV_MSG_ELEM_LEN 128 + +enum rte_dev_state { + RTE_DEV_UNDEFINED, /**< unknown device state */ + RTE_DEV_FAULT, /**< device fault or error */ + RTE_DEV_PARSED, /**< device has been scanned on bus*/ + RTE_DEV_PROBED, /**< device has been probed driver */ +}; + +enum rte_dev_event_subsystem { + RTE_DEV_EVENT_SUBSYSTEM_UNKNOWN, + RTE_DEV_EVENT_SUBSYSTEM_UIO, + RTE_DEV_EVENT_SUBSYSTEM_VFIO, + RTE_DEV_EVENT_SUBSYSTEM_MAX +}; + /** * The device event type. */ diff --git a/lib/librte_eal/linuxapp/eal/eal_dev.c b/lib/librte_eal/linuxapp/eal/eal_dev.c index 9d9e088..2b34e2c 100644 --- a/lib/librte_eal/linuxapp/eal/eal_dev.c +++ b/lib/librte_eal/linuxapp/eal/eal_dev.c @@ -78,9 +78,102 @@ dev_uev_monitor_create(int netlink_fd) } static void +dev_uev_parse(const char *buf, struct rte_dev_event *event) +{ + char action[RTE_EAL_UEV_MSG_ELEM_LEN]; + char subsystem[RTE_EAL_UEV_MSG_ELEM_LEN]; + char dev_path[RTE_EAL_UEV_MSG_ELEM_LEN]; + char pci_slot_name[RTE_EAL_UEV_MSG_ELEM_LEN]; + int i = 0; + + memset(action, 0, RTE_EAL_UEV_MSG_ELEM_LEN); + memset(subsystem, 0, RTE_EAL_UEV_MSG_ELEM_LEN); + memset(dev_path, 0, RTE_EAL_UEV_MSG_ELEM_LEN); + memset(pci_slot_name, 0, RTE_EAL_UEV_MSG_ELEM_LEN); + + while (i < RTE_EAL_UEV_MSG_LEN) { + for (; i < RTE_EAL_UEV_MSG_LEN; i++) { + if (*buf) + break; + buf++; + } + /** + * check device uevent from kernel side, no need to check + * uevent from udev. + */ + if (!strncmp(buf, "libudev", 7)) { + buf += 7; + i += 7; + return; + } + if (!strncmp(buf, "ACTION=", 7)) { + buf += 7; + i += 7; + snprintf(action, sizeof(action), "%s", buf); + } else if (!strncmp(buf, "DEVPATH=", 8)) { + buf += 8; + i += 8; + snprintf(dev_path, sizeof(dev_path), "%s", buf); + } else if (!strncmp(buf, "SUBSYSTEM=", 10)) { + buf += 10; + i += 10; + snprintf(subsystem, sizeof(subsystem), "%s", buf); + } else if (!strncmp(buf, "PCI_SLOT_NAME=", 14)) { + buf += 14; + i += 14; + snprintf(pci_slot_name, sizeof(subsystem), "%s", buf); + event->devname = pci_slot_name; + } + for (; i < RTE_EAL_UEV_MSG_LEN; i++) { + if (*buf == '\0') + break; + buf++; + } + } + + if ((!strncmp(subsystem, "uio", 3)) || + (!strncmp(subsystem, "pci", 3))) + event->subsystem = RTE_DEV_EVENT_SUBSYSTEM_UIO; + if (!strncmp(action, "add", 3)) + event->type = RTE_DEV_EVENT_ADD; + if (!strncmp(action, "remove", 6)) + event->type = RTE_DEV_EVENT_REMOVE; +} + +static int +dev_uev_receive(int fd, struct rte_dev_event *uevent) +{ + int ret; + char buf[RTE_EAL_UEV_MSG_LEN]; + + memset(uevent, 0, sizeof(struct rte_dev_event)); + memset(buf, 0, RTE_EAL_UEV_MSG_LEN); + + ret = recv(fd, buf, RTE_EAL_UEV_MSG_LEN - 1, MSG_DONTWAIT); + if (ret < 0) { + RTE_LOG(ERR, EAL, + "Socket read error(%d): %s\n", + errno, strerror(errno)); + return -1; + } else if (ret == 0) + /* connection closed */ + return -1; + + dev_uev_parse(buf, uevent); + + return 0; +} + +static void dev_uev_process(__rte_unused void *param) { - /* TODO: device uevent processing */ + struct rte_dev_event uevent; + + if (dev_uev_receive(intr_handle.fd, &uevent)) + return; + + if (uevent.devname) + _rte_dev_callback_process(uevent.devname, uevent.type, NULL); } int __rte_experimental -- 2.7.4