From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-ea0-x22e.google.com (mail-ea0-x22e.google.com [IPv6:2a00:1450:4013:c01::22e]) by dpdk.org (Postfix) with ESMTP id A0308156 for ; Wed, 4 Dec 2013 16:38:03 +0100 (CET) Received: by mail-ea0-f174.google.com with SMTP id b10so10591865eae.5 for ; Wed, 04 Dec 2013 07:39:05 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:date:message-id:subject:from:to:content-type; bh=ESkUkEo0DKbDMDROx+e9BtWtrqS0+I+ErfhG5/ZqewI=; b=Zo8ByiAL3DcwhBwW0dT07MHRZYrCVGbEDs1gyCigQVDzpWkyGBSX5AitM4XWLfOl8U wMHVCc+zJv56CiJXV6y4+uMNdl+LlumR84UebnbzIFbbTIsAsr1P9qCJgkJjXwqnnsEx gbY0nDKBdeBtTLjrbVfnN0MxHbK85uQ5lhYjbx2WrjErMH6Xw+BoYGE/97zKmzCcF4RE 7X8EIJmkYKdHgm2HKxfHOWuWnADwK9mb0LK4ARgm/QHfBW5OCftLTmi7BOOMHRt74Sg7 yR1ENvQEoyWLDM2yM9ETUxdRUfBRoT5/DUEUMkFg/XEz0ziJGyaTLSgtJH2e+4lYHmqY Bssw== MIME-Version: 1.0 X-Received: by 10.15.111.201 with SMTP id cj49mr11660535eeb.56.1386171545743; Wed, 04 Dec 2013 07:39:05 -0800 (PST) Received: by 10.15.94.5 with HTTP; Wed, 4 Dec 2013 07:39:05 -0800 (PST) Date: Wed, 4 Dec 2013 16:39:05 +0100 Message-ID: From: Mats Liljegren To: "dev@dpdk.org" Content-Type: text/plain; charset=UTF-8 Subject: [dpdk-dev] [PATCH] RFC: Introduce host_ifname field to struct rte_eth_dev_info X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 04 Dec 2013 15:38:04 -0000 I played around with pcap to compare it against "pure" DPDK user-space driver. I realized that interrupt affinity suddenly becomes important, since it uses interrupts. So I needed a way to set it. The only place where I know which core will handle which pcap interface, is within my DPDK application. But DPDK did not save the host interface name anywhere, so it was nowhere to be found. I created a patch for this, found below. Is this something that could be upstreamed? Best regards Mats Liljegren -- >8 -- >>From 1b126c7f74680afae8a6426a197d77eab0f2b75e Mon Sep 17 00:00:00 2001 From: Mats Liljegren Date: Wed, 4 Dec 2013 16:31:59 +0100 Subject: [PATCH] Introduce host_ifname field to struct rte_eth_dev_info This field is intended for pcap to describe the name of the interface as known to Linux, e.g. eth2. When using pcap interrupt affinity becomes important, and this field gives the application a chance to ensure that interrupt affinity is set to to the lcore handling the device. An example how to use it: static void ensure_irq_affinity(unsigned port) { char path[255]; struct dirent *dirent; DIR *dir; const unsigned lcore = rte_lcore_id(); struct rte_eth_dev_info dev_info; rte_eth_dev_info_get(port, &dev_info); if (dev_info.host_ifname[0] == '\0') /* No host interface name */ return; snprintf(path, sizeof (path), "/sys/class/net/%s/device/msi_irqs", dev_info.host_ifname); dir = opendir(path); if (dir == NULL) /* Can't do anything for this interface */ return; for (dirent = readdir(dir); dirent != NULL; dirent = readdir(dir)) { FILE *file; if ((dirent->d_name[0] < '0') || (dirent->d_name[0] > '9')) continue; snprintf(path, sizeof (path), "/proc/irq/%s/smp_affinity", dirent->d_name); file = fopen(path, "w"); if (file == NULL) rte_exit(EXIT_FAILURE, "%s: Could not open file for writing: %s\n", path, strerror(errno)); fprintf(file, "%x", 1 << lcore); TRY(fclose(file)); printf("%s: Affinity set to 0x%x\n", dev_info.host_ifname, 1 << lcore); } closedir(dir); } Signed-off-by: Mats Liljegren --- lib/librte_ether/rte_ethdev.c | 1 + lib/librte_ether/rte_ethdev.h | 1 + lib/librte_pmd_pcap/rte_eth_pcap.c | 42 ++++++++++++++++++++++++++++++-------- lib/librte_pmd_pcap/rte_eth_pcap.h | 7 +++++-- 4 files changed, 41 insertions(+), 10 deletions(-) diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c index 675f247..bf126cf 100644 --- a/lib/librte_ether/rte_ethdev.c +++ b/lib/librte_ether/rte_ethdev.c @@ -1037,6 +1037,7 @@ rte_eth_dev_info_get(uint8_t port_id, struct rte_eth_dev_info *dev_info) /* Default device offload capabilities to zero */ dev_info->rx_offload_capa = 0; dev_info->tx_offload_capa = 0; + dev_info->host_ifname = ""; FUNC_PTR_OR_RET(*dev->dev_ops->dev_infos_get); (*dev->dev_ops->dev_infos_get)(dev, dev_info); dev_info->pci_dev = dev->pci_dev; diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h index 41268e1..8542911 100644 --- a/lib/librte_ether/rte_ethdev.h +++ b/lib/librte_ether/rte_ethdev.h @@ -786,6 +786,7 @@ struct rte_eth_conf { struct rte_eth_dev_info { struct rte_pci_device *pci_dev; /**< Device PCI information. */ const char *driver_name; /**< Device Driver name. */ + const char *host_ifname; /**< Name of interface as known to Linux, or empty string. */ uint32_t min_rx_bufsize; /**< Minimum size of RX buffer. */ uint32_t max_rx_pktlen; /**< Maximum configurable length of RX pkt. */ uint16_t max_rx_queues; /**< Maximum number of RX queues. */ diff --git a/lib/librte_pmd_pcap/rte_eth_pcap.c b/lib/librte_pmd_pcap/rte_eth_pcap.c index 08a944c..30bdd0c 100644 --- a/lib/librte_pmd_pcap/rte_eth_pcap.c +++ b/lib/librte_pmd_pcap/rte_eth_pcap.c @@ -87,6 +87,8 @@ struct pmd_internals { unsigned nb_rx_queues; unsigned nb_tx_queues; + char *iface_name; + struct pcap_rx_queue rx_queue[RTE_PMD_RING_MAX_RX_RINGS]; struct pcap_tx_queue tx_queue[RTE_PMD_RING_MAX_TX_RINGS]; }; @@ -284,6 +286,7 @@ eth_dev_info(struct rte_eth_dev *dev, { struct pmd_internals *internals = dev->data->dev_private; dev_info->driver_name = drivername; + dev_info->host_ifname = internals->iface_name; dev_info->max_mac_addrs = 1; dev_info->max_rx_pktlen = (uint32_t) -1; dev_info->max_rx_queues = (uint16_t)internals->nb_rx_queues; @@ -527,10 +530,22 @@ rte_pmd_init_internals(const unsigned nb_rx_queues, const unsigned nb_tx_queues, const unsigned numa_node, struct pmd_internals **internals, - struct rte_eth_dev **eth_dev) + struct rte_eth_dev **eth_dev, + struct args_dict *dict) { struct rte_eth_dev_data *data = NULL; struct rte_pci_device *pci_dev = NULL; + unsigned k_idx; + struct key_value *pair; + + for (k_idx = 0; k_idx < dict->index; k_idx++) { + pair = &dict->pairs[k_idx]; + if (strstr(pair->key, ETH_PCAP_IFACE_ARG) != NULL) + break; + } + + if (k_idx == dict->index) + goto error; RTE_LOG(INFO, PMD, "Creating pcap-backed ethdev on numa socket %u\n", numa_node); @@ -550,6 +565,12 @@ rte_pmd_init_internals(const unsigned nb_rx_queues, if (*internals == NULL) goto error; + (*internals)->iface_name = rte_zmalloc_socket( + NULL, strlen(pair->value) + 1, 0, numa_node); + if ((*internals)->iface_name == NULL) + goto error; + strcpy((*internals)->iface_name, pair->value); + /* reserve an ethdev entry */ *eth_dev = rte_eth_dev_allocate(); if (*eth_dev == NULL) @@ -588,6 +609,8 @@ rte_pmd_init_internals(const unsigned nb_rx_queues, rte_free(pci_dev); if (*internals) rte_free(*internals); + if ((*internals)->iface_name) + rte_free((*internals)->iface_name); return -1; } @@ -596,7 +619,8 @@ rte_eth_from_pcaps_n_dumpers(pcap_t * const rx_queues[], const unsigned nb_rx_queues, pcap_dumper_t * const tx_queues[], const unsigned nb_tx_queues, - const unsigned numa_node) + const unsigned numa_node, + struct args_dict *dict) { struct pmd_internals *internals = NULL; struct rte_eth_dev *eth_dev = NULL; @@ -609,7 +633,7 @@ rte_eth_from_pcaps_n_dumpers(pcap_t * const rx_queues[], return -1; if (rte_pmd_init_internals(nb_rx_queues, nb_tx_queues, numa_node, - &internals, ð_dev) < 0) + &internals, ð_dev, dict) < 0) return -1; for (i = 0; i < nb_rx_queues; i++) { @@ -630,7 +654,8 @@ rte_eth_from_pcaps(pcap_t * const rx_queues[], const unsigned nb_rx_queues, pcap_t * const tx_queues[], const unsigned nb_tx_queues, - const unsigned numa_node) + const unsigned numa_node, + struct args_dict *dict) { struct pmd_internals *internals = NULL; struct rte_eth_dev *eth_dev = NULL; @@ -643,7 +668,7 @@ rte_eth_from_pcaps(pcap_t * const rx_queues[], return -1; if (rte_pmd_init_internals(nb_rx_queues, nb_tx_queues, numa_node, - &internals, ð_dev) < 0) + &internals, ð_dev, dict) < 0) return -1; for (i = 0; i < nb_rx_queues; i++) { @@ -691,7 +716,8 @@ rte_pmd_pcap_init(const char *name, const char *params) if (ret < 0) return -1; - return rte_eth_from_pcaps(pcaps.pcaps, 1, pcaps.pcaps, 1, numa_node); + return rte_eth_from_pcaps(pcaps.pcaps, 1, pcaps.pcaps, 1, numa_node, + &dict); } /* @@ -732,10 +758,10 @@ rte_pmd_pcap_init(const char *name, const char *params) if (using_dumpers) return rte_eth_from_pcaps_n_dumpers(pcaps.pcaps, pcaps.num_of_rx, - dumpers.dumpers, dumpers.num_of_tx, numa_node); + dumpers.dumpers, dumpers.num_of_tx, numa_node, &dict); return rte_eth_from_pcaps(pcaps.pcaps, pcaps.num_of_rx, dumpers.pcaps, - dumpers.num_of_tx, numa_node); + dumpers.num_of_tx, numa_node, &dict); } diff --git a/lib/librte_pmd_pcap/rte_eth_pcap.h b/lib/librte_pmd_pcap/rte_eth_pcap.h index 368ed88..4a237a4 100644 --- a/lib/librte_pmd_pcap/rte_eth_pcap.h +++ b/lib/librte_pmd_pcap/rte_eth_pcap.h @@ -38,6 +38,7 @@ extern "C" { #endif #include +#include "rte_eth_pcap_arg_parser.h" #ifdef pcap_sendpacket #define PCAP_CAN_SEND @@ -51,13 +52,15 @@ int rte_eth_from_pcaps(pcap_t * const rx_queues[], const unsigned nb_rx_queues, pcap_t * const tx_queues[], const unsigned nb_tx_queues, - const unsigned numa_node); + const unsigned numa_node, + struct args_dict *dict); int rte_eth_from_pcaps_n_dumpers(pcap_t * const rx_queues[], const unsigned nb_rx_queues, pcap_dumper_t * const tx_queues[], const unsigned nb_tx_queues, - const unsigned numa_node); + const unsigned numa_node, + struct args_dict *dict); /** * For use by the EAL only. Called as part of EAL init to set up any dummy NICs -- 1.8.3.2