DPDK patches and discussions
 help / color / mirror / Atom feed
From: Cunming Liang <cunming.liang@intel.com>
To: dev@dpdk.org
Subject: [dpdk-dev] [RFC PATCH 2/6] eal: direct ring access support by linux af_packet
Date: Tue, 25 Nov 2014 22:11:18 +0800	[thread overview]
Message-ID: <1416924682-24170-3-git-send-email-cunming.liang@intel.com> (raw)
In-Reply-To: <1416924682-24170-1-git-send-email-cunming.liang@intel.com>


Signed-off-by: Cunming Liang <cunming.liang@intel.com>
---
 lib/librte_eal/linuxapp/eal/Makefile         |   1 +
 lib/librte_eal/linuxapp/eal/eal_pci_bifurc.c | 336 +++++++++++++++++++++++++++
 2 files changed, 337 insertions(+)
 create mode 100644 lib/librte_eal/linuxapp/eal/eal_pci_bifurc.c

diff --git a/lib/librte_eal/linuxapp/eal/Makefile b/lib/librte_eal/linuxapp/eal/Makefile
index 06c1dc5..f775203 100644
--- a/lib/librte_eal/linuxapp/eal/Makefile
+++ b/lib/librte_eal/linuxapp/eal/Makefile
@@ -61,6 +61,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_EAL_LINUXAPP) += eal_pci.c
 SRCS-$(CONFIG_RTE_LIBRTE_EAL_LINUXAPP) += eal_pci_uio.c
 SRCS-$(CONFIG_RTE_LIBRTE_EAL_LINUXAPP) += eal_pci_vfio.c
 SRCS-$(CONFIG_RTE_LIBRTE_EAL_LINUXAPP) += eal_pci_vfio_mp_sync.c
+SRCS-$(CONFIG_RTE_LIBRTE_EAL_LINUXAPP) += eal_pci_bifurc.c
 SRCS-$(CONFIG_RTE_LIBRTE_EAL_LINUXAPP) += eal_debug.c
 SRCS-$(CONFIG_RTE_LIBRTE_EAL_LINUXAPP) += eal_lcore.c
 SRCS-$(CONFIG_RTE_LIBRTE_EAL_LINUXAPP) += eal_timer.c
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci_bifurc.c b/lib/librte_eal/linuxapp/eal/eal_pci_bifurc.c
new file mode 100644
index 0000000..94ad4df
--- /dev/null
+++ b/lib/librte_eal/linuxapp/eal/eal_pci_bifurc.c
@@ -0,0 +1,336 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <linux/if_ether.h>
+#include <linux/if_packet.h>
+#include <arpa/inet.h>
+#include <net/if.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+
+#include <rte_malloc.h>
+#include <rte_dev.h>
+#include <rte_pci.h>
+#include <rte_log.h>
+#include <rte_devargs.h>
+#include <rte_pci_bifurc.h>
+
+int
+rte_eal_bifurc_get_ifinfo(int sockfd, char *iface_name,
+			  int *if_index, uint8_t *hwaddr, int *mtu)
+{
+	struct ifreq req;
+
+	if (iface_name == NULL)
+		return -1;
+
+	memset(&req, 0, sizeof(req));
+
+	/* request for ifindex */
+	if (if_index) {
+		memcpy(req.ifr_name, iface_name, IFNAMSIZ);
+		if (ioctl(sockfd, SIOCGIFINDEX, &req) == -1) {
+			RTE_LOG(ERR, EAL,
+				"%s: ioctl failed (SIOCGIFINDEX)\n",
+				iface_name);
+			return -1;
+		}
+		*if_index = req.ifr_ifindex;
+	}
+
+	/* request for hwaddr */
+	if (hwaddr) {
+		if (ioctl(sockfd, SIOCGIFHWADDR, &req) == -1) {
+			RTE_LOG(ERR, EAL,
+				"%s: ioctl failed (SIOCGIFHWADDR)\n",
+				iface_name);
+			return -1;
+		}
+		memcpy(hwaddr, req.ifr_hwaddr.sa_data, IFHWADDRLEN);
+	}
+
+	/* request for mtu */
+	if (mtu) {
+		if (ioctl(sockfd, SIOCGIFMTU, &req) == -1) {
+			RTE_LOG(ERR, EAL,
+				"%s: ioctl failed (SIOCGIFMTU)\n",
+				iface_name);
+			return -1;
+		}
+		*mtu = req.ifr_mtu;
+	}
+
+	return 0;
+}
+
+static int
+get_map_size(int sockfd, uint32_t *size)
+{
+	struct tpacket_dev_qpair_map_region_info info;
+	socklen_t optlen;
+	int ret;
+
+	/* request for map region info */
+	optlen = sizeof(struct tpacket_dev_qpair_map_region_info);
+	ret = getsockopt(sockfd, SOL_PACKET, PACKET_DEV_QPAIR_MAP_REGION_INFO,
+			 &info, &optlen);
+	if (ret == -1) {
+		RTE_LOG(ERR, PMD,
+			"could not get PACKET_DEV_QPAIR_MAP_REGION_INFO "
+			"on AF_PACKET socket, errno = %d\n", errno);
+		return -1;
+	}
+
+	*size = info.tp_dev_bar_sz;
+	return 0;
+}
+
+/* map PCIE configure space of queue pairs */
+int
+rte_eal_bifurc_map(int sockfd, void **addr, uint32_t *size)
+{
+	if (addr == NULL || size == NULL)
+		return -1;
+
+	if (get_map_size(sockfd, size))
+		return -1;
+
+	*addr = mmap(NULL, *size, PROT_READ | PROT_WRITE,
+		     MAP_SHARED, sockfd, 0);
+	if (*addr == MAP_FAILED) {
+		RTE_LOG(ERR, EAL,
+			"call to mmap failed on AF_PACKET socket %d\n",
+			sockfd);
+		return -1;
+	}
+
+	RTE_LOG(INFO, EAL,
+		"mapping sockfd %d PCIE configuraiton space,"
+		"address = %p, size = 0x%x\n", sockfd,
+		*addr, *size);
+
+	return 0;
+}
+
+void
+rte_eal_bifurc_unmap(int sockfd, void *addr)
+{
+	uint32_t size;
+
+	if (addr && !get_map_size(sockfd, &size))
+		munmap(addr, size);
+}
+
+/* split queue pairs */
+int
+rte_eal_bifurc_split(int sockfd, uint32_t *nb_qp, uint32_t *qp_start)
+{
+	struct tpacket_dev_qpairs_info qpairs_info;
+	socklen_t optlen;
+	int ret;
+
+	optlen = sizeof(struct tpacket_dev_qpairs_info);
+
+	/* request for qpairs split */
+	qpairs_info.tp_qpairs_start_from = -1;
+	qpairs_info.tp_qpairs_num = *nb_qp;
+	ret = setsockopt(sockfd, SOL_PACKET, PACKET_RXTX_QPAIRS_SPLIT,
+			&qpairs_info, optlen);
+	if (ret == -1) {
+		RTE_LOG(ERR, EAL,
+			"request PACKET_RXTX_QPAIRS_SPLIT on AF_PACKET "
+			"socket for %d fail, errno = %d\n",
+			sockfd, errno);
+		return -1;
+	}
+
+	/* parse respone of qpairs split */
+	ret = getsockopt(sockfd, SOL_PACKET, PACKET_RXTX_QPAIRS_SPLIT,
+			 &qpairs_info, &optlen);
+	if (ret == -1) {
+		RTE_LOG(ERR, EAL,
+			"could not get PACKET_RXTX_QPAIRS_SPLIT on AF_PACKET "
+			"socket for %d, errno = %d\n", sockfd, errno);
+		return -1;
+	}
+
+	*nb_qp    = qpairs_info.tp_qpairs_num;
+	*qp_start = qpairs_info.tp_qpairs_start_from;
+
+	RTE_LOG(INFO, EAL,
+		"kernel driver allocates queue pairs from %u to %u\n",
+		qpairs_info.tp_qpairs_start_from,
+		qpairs_info.tp_qpairs_start_from +
+		qpairs_info.tp_qpairs_num - 1);
+
+	return 0;
+}
+
+/* retire queue pairs back */
+void
+rte_eal_bifurc_retire(int sockfd, uint32_t nb_qp, uint32_t qp_start)
+{
+	struct tpacket_dev_qpairs_info qpairs_info;
+	int ret;
+
+	/* return queues to kernel driver */
+	qpairs_info.tp_qpairs_start_from = qp_start;
+	qpairs_info.tp_qpairs_num        = nb_qp;
+	ret = setsockopt(sockfd, SOL_PACKET, PACKET_RXTX_QPAIRS_RETURN,
+			 &qpairs_info, sizeof(qpairs_info));
+	if (ret == -1)
+		RTE_LOG(ERR, EAL,
+			"could not set PACKET_RXTX_QPAIRS_RETURN on AF_PACKET "
+			"socket %d for queue pairs from %d to %d\n",
+			sockfd, qp_start, qp_start + nb_qp - 1);
+}
+
+/*
+ * Opens an AF_PACKET socket
+ */
+int
+rte_eal_bifurc_open(int *sockfd)
+{
+	/* Open an AF_PACKET socket... */
+	if (sockfd)
+		*sockfd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
+
+	if (!sockfd || *sockfd == -1) {
+		RTE_LOG(ERR, EAL, "Could not open AF_PACKET socket\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+int
+rte_eal_bifurc_bind(int sockfd, int if_index)
+{
+	struct sockaddr_ll sockaddr;
+	int ret;
+
+	/* af_packet bind iface with sockfd */
+	memset(&sockaddr, 0, sizeof(sockaddr));
+	sockaddr.sll_family = AF_PACKET;
+	sockaddr.sll_protocol = htons(ETH_P_ALL);
+	sockaddr.sll_ifindex = if_index;
+	ret = bind(sockfd, (const struct sockaddr *)&sockaddr,
+		   sizeof(sockaddr));
+	if (ret == -1) {
+		RTE_LOG(ERR, EAL, "could not bind AF_PACKET socket to %d\n",
+			if_index);
+		return ret;
+	}
+
+	return 0;
+}
+
+int
+rte_eal_bifurc_set_pci(int sockfd, struct rte_pci_device *pci_dev)
+{
+	struct tpacket_dev_info dev_info;
+	socklen_t optlen;
+	int ret;
+
+	/* request for desc info */
+	optlen = sizeof(struct tpacket_dev_info);
+	ret = getsockopt(sockfd, SOL_PACKET, PACKET_DEV_DESC_INFO,
+			 &dev_info, &optlen);
+	if (ret == -1) {
+		RTE_LOG(ERR, EAL,
+			"could not get PACKET_DEV_DESC_INFO on AF_PACKET "
+			"socket for %d, errno = %d\n", sockfd, errno);
+		return -1;
+	}
+
+	RTE_LOG(INFO, EAL,
+		"vendorid = 0x%x, deviceid = 0x%x, "
+		"num of qpairs = %d, insue qpairs = %d\n",
+		 dev_info.tp_vendor_id, dev_info.tp_device_id,
+		 dev_info.tp_num_total_qpairs, dev_info.tp_num_inuse_qpairs);
+
+	/* pci_dev update and mmap configure space */
+	memset(pci_dev, 0, sizeof(*pci_dev));
+	pci_dev->id.vendor_id = dev_info.tp_vendor_id;
+	pci_dev->id.device_id = dev_info.tp_device_id;
+	pci_dev->id.subsystem_vendor_id = PCI_ANY_ID;
+	pci_dev->id.subsystem_device_id = PCI_ANY_ID;
+	pci_dev->numa_node = dev_info.tp_numa_node;
+
+	return 0;
+}
+
+struct rte_devargs *
+rte_eal_bifurc_get_devargs(const char *drv_name, const char *args)
+{
+	struct rte_devargs *devargs;
+	int ret;
+
+	devargs = malloc(sizeof(*devargs));
+	if (devargs == NULL) {
+		RTE_LOG(ERR, EAL, "cannot allocate devargs\n");
+		return NULL;
+	}
+	memset(devargs, 0, sizeof(*devargs));
+	devargs->type = RTE_DEVTYPE_VIRTUAL;
+
+	ret = snprintf(devargs->virtual.drv_name,
+		       sizeof(devargs->virtual.drv_name), "%s", drv_name);
+	if (ret < 0 || ret >= (int)sizeof(devargs->virtual.drv_name)) {
+		RTE_LOG(ERR, EAL,
+			"driver name too large: <%s>\n", drv_name);
+		free(devargs);
+		return NULL;
+	}
+
+	ret = snprintf(devargs->args, sizeof(devargs->args), "%s", args);
+	if (ret < 0 || ret >= (int)sizeof(devargs->args)) {
+		RTE_LOG(ERR, EAL,
+			"driver args too large: <%s>\n", args);
+		free(devargs);
+		return NULL;
+	}
+	return devargs;
+}
+
+void
+rte_eal_bifurc_put_devargs(struct rte_devargs *devargs)
+{
+	if (devargs != NULL)
+		free(devargs);
+}
-- 
1.8.1.4

  parent reply	other threads:[~2014-11-25 14:04 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-11-25 14:11 [dpdk-dev] [RFC PATCH 0/6] DPDK support to bifurcated driver Cunming Liang
2014-11-25 14:11 ` [dpdk-dev] [RFC PATCH 1/6] eal: common direct ring access API Cunming Liang
2014-11-25 14:11 ` Cunming Liang [this message]
2014-11-25 14:11 ` [dpdk-dev] [RFC PATCH 3/6] pci: allow VDEV as pci device during device driver probe Cunming Liang
2014-11-25 14:11 ` [dpdk-dev] [RFC PATCH 4/6] bifurc: add driver to scan bifurcated netdev Cunming Liang
2014-11-25 14:11 ` [dpdk-dev] [RFC PATCH 5/6] ixgbe: rx/tx queue stop bug fix Cunming Liang
2014-11-26  0:44   ` Ouyang, Changchun
2014-11-25 14:11 ` [dpdk-dev] [RFC PATCH 6/6] ixgbe: PMD for bifurc ixgbe net device Cunming Liang
2014-11-25 14:34   ` Bruce Richardson
2014-11-25 14:48     ` Liang, Cunming
2014-11-25 15:01       ` Bruce Richardson
2014-11-26  8:22         ` Liang, Cunming
2014-11-26 10:35           ` Bruce Richardson
2014-11-25 14:23 ` [dpdk-dev] [RFC PATCH 0/6] DPDK support to bifurcated driver Neil Horman
2014-11-25 14:29   ` Bruce Richardson
2014-11-25 14:40     ` Liang, Cunming
2014-11-25 14:46       ` Zhou, Danny
2014-11-25 14:57     ` Walukiewicz, Miroslaw
2014-11-25 15:02       ` Bruce Richardson
2014-11-25 15:23         ` Zhou, Danny
2014-11-26 10:45           ` Walukiewicz, Miroslaw
2014-11-26 12:22             ` Zhou, Danny
2015-04-09  3:43 ` 贾学涛
2015-04-20  9:53   ` Shelton Chia

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=1416924682-24170-3-git-send-email-cunming.liang@intel.com \
    --to=cunming.liang@intel.com \
    --cc=dev@dpdk.org \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).