From patchwork Sun Mar 4 15:30:03 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jianfeng Tan X-Patchwork-Id: 35631 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 6B3645F11; Sun, 4 Mar 2018 16:28:24 +0100 (CET) Received: from mga05.intel.com (mga05.intel.com [192.55.52.43]) by dpdk.org (Postfix) with ESMTP id A7D7820BD for ; Sun, 4 Mar 2018 16:28:21 +0100 (CET) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga105.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 04 Mar 2018 07:28:19 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.47,423,1515484800"; d="scan'208";a="35375913" Received: from dpdk06.sh.intel.com ([10.67.110.196]) by fmsmga001.fm.intel.com with ESMTP; 04 Mar 2018 07:28:18 -0800 From: Jianfeng Tan To: dev@dpdk.org Cc: bruce.richardson@intel.com, konstantin.ananyev@intel.com, thomas@monjalon.net, maxime.coquelin@redhat.com, ferruh.yigit@intel.com, anatoly.burakov@intel.com, Jianfeng Tan Date: Sun, 4 Mar 2018 15:30:03 +0000 Message-Id: <1520177405-59091-3-git-send-email-jianfeng.tan@intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1520177405-59091-1-git-send-email-jianfeng.tan@intel.com> References: <1520177405-59091-1-git-send-email-jianfeng.tan@intel.com> Subject: [dpdk-dev] [PATCH 2/4] bus/vdev: bus scan by multi-process channel 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: , Errors-To: dev-bounces@dpdk.org Sender: "dev" To scan the vdevs in primary, we send request to primary process to obtain the names for vdevs. Only the name is shared from the primary. In probe(), the device driver is supposed to locate (or request more) the detail information from the primary. Signed-off-by: Jianfeng Tan --- drivers/bus/vdev/Makefile | 1 + drivers/bus/vdev/vdev.c | 110 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 111 insertions(+) diff --git a/drivers/bus/vdev/Makefile b/drivers/bus/vdev/Makefile index 24d424a..bd0bb89 100644 --- a/drivers/bus/vdev/Makefile +++ b/drivers/bus/vdev/Makefile @@ -10,6 +10,7 @@ LIB = librte_bus_vdev.a CFLAGS += -O3 CFLAGS += $(WERROR_FLAGS) +CFLAGS += -DALLOW_EXPERIMENTAL_API # versioning export map EXPORT_MAP := rte_bus_vdev_version.map diff --git a/drivers/bus/vdev/vdev.c b/drivers/bus/vdev/vdev.c index e4bc724..0a3ea52 100644 --- a/drivers/bus/vdev/vdev.c +++ b/drivers/bus/vdev/vdev.c @@ -314,6 +314,88 @@ rte_vdev_uninit(const char *name) return 0; } +struct vdev_param { +#define VDEV_SCAN_REQ 1 +#define VDEV_SCAN_ONE 2 +#define VDEV_SCAN_REP 3 + int type; + int num; + char name[RTE_DEV_NAME_MAX_LEN]; +}; + +static int vdev_plug(struct rte_device *dev); + +static int +vdev_action(const struct rte_mp_msg *mp_msg, const void *peer) +{ + struct rte_vdev_device *dev; + struct rte_devargs *devargs; + struct rte_mp_msg mp_resp; + struct vdev_param *ou = (struct vdev_param *)&mp_resp.param; + const struct vdev_param *in = (const struct vdev_param *)mp_msg->param; + const char *devname; + int num; + + strcpy(mp_resp.name, "vdev"); + mp_resp.len_param = sizeof(*ou); + mp_resp.num_fds = 0; + + switch (in->type) { + case VDEV_SCAN_REQ: + ou->type = VDEV_SCAN_ONE; + ou->num = 1; + num = 0; + TAILQ_FOREACH(dev, &vdev_device_list, next) { + devname = rte_vdev_device_name(dev); + if (strlen(devname) == 0) + VDEV_LOG(INFO, "vdev with no name is not sent"); + VDEV_LOG(INFO, "send vdev, %s", devname); + strncpy(ou->name, devname, RTE_DEV_NAME_MAX_LEN); + if (rte_mp_sendmsg(&mp_resp) < 0) + VDEV_LOG(ERR, "send vdev, %s, failed, %s", + devname, strerror(rte_errno)); + num++; + } + ou->type = VDEV_SCAN_REP; + ou->num = num; + if (rte_mp_reply(&mp_resp, peer) < 0) + VDEV_LOG(ERR, "Failed to reply a scan request"); + break; + case VDEV_SCAN_ONE: + VDEV_LOG(INFO, "receive vdev, %s", in->name); + dev = find_vdev(in->name); + if (dev) { + VDEV_LOG(ERR, "vdev already exists: %s", in->name); + break; + } + + devargs = alloc_devargs(in->name, NULL); + if (!devargs) { + VDEV_LOG(ERR, "failed to allocate memory"); + break; + } + + dev = calloc(1, sizeof(*dev)); + if (!dev) { + VDEV_LOG(ERR, "failed to allocate memory"); + free(devargs); + break; + } + + dev->device.devargs = devargs; + dev->device.numa_node = 0; /* to be corrected in probe() */ + dev->device.name = devargs->name; + + TAILQ_INSERT_TAIL(&devargs_list, devargs, next); + TAILQ_INSERT_TAIL(&vdev_device_list, dev, next); + break; + default: + VDEV_LOG(ERR, "vdev cannot recognize this message"); + } + + return 0; +} + static int vdev_scan(void) { @@ -321,6 +403,34 @@ vdev_scan(void) struct rte_devargs *devargs; struct vdev_custom_scan *custom_scan; + if (rte_mp_action_register("vdev", vdev_action) < 0 && + rte_errno != EEXIST) { + VDEV_LOG(ERR, "vdev fails to add action"); + return -1; + } + + if (rte_eal_process_type() == RTE_PROC_SECONDARY) { + struct rte_mp_msg mp_req, *mp_rep; + struct rte_mp_reply mp_reply; + struct timespec ts = {.tv_sec = 5, .tv_nsec = 0}; + struct vdev_param *req = (struct vdev_param *)mp_req.param; + struct vdev_param *resp; + + strcpy(mp_req.name, "vdev"); + mp_req.len_param = sizeof(*req); + mp_req.num_fds = 0; + req->type = VDEV_SCAN_REQ; + if (rte_mp_request(&mp_req, &mp_reply, &ts) == 0 && + mp_reply.nb_received == 1) { + mp_rep = &mp_reply.msgs[0]; + resp = (struct vdev_param *)mp_rep->param; + VDEV_LOG(INFO, "Received %d vdevs", resp->num); + } else + VDEV_LOG(ERR, "Failed to request vdev from primary"); + + /* Fall through to allow private vdevs in secondary process */ + } + /* call custom scan callbacks if any */ rte_spinlock_lock(&vdev_custom_scan_lock); TAILQ_FOREACH(custom_scan, &vdev_custom_scans, next) {