DPDK patches and discussions
 help / color / mirror / Atom feed
* [dpdk-dev] [PATCH] RFC: Introduce host_ifname field to struct rte_eth_dev_info
@ 2013-12-04 15:39 Mats Liljegren
  2014-01-02 13:51 ` Thomas Monjalon
  2014-01-02 16:36 ` Stephen Hemminger
  0 siblings, 2 replies; 3+ messages in thread
From: Mats Liljegren @ 2013-12-04 15:39 UTC (permalink / raw)
  To: dev

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 <mats.liljegren@enea.com>
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 <mats.liljegren@enea.com>
---
 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, &eth_dev) < 0)
+           &internals, &eth_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, &eth_dev) < 0)
+           &internals, &eth_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 <pcap.h>
+#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

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [dpdk-dev] [PATCH] RFC: Introduce host_ifname field to struct rte_eth_dev_info
  2013-12-04 15:39 [dpdk-dev] [PATCH] RFC: Introduce host_ifname field to struct rte_eth_dev_info Mats Liljegren
@ 2014-01-02 13:51 ` Thomas Monjalon
  2014-01-02 16:36 ` Stephen Hemminger
  1 sibling, 0 replies; 3+ messages in thread
From: Thomas Monjalon @ 2014-01-02 13:51 UTC (permalink / raw)
  To: Mats Liljegren; +Cc: dev

Hello,

04/12/2013 16:39, Mats Liljegren :
> 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?

Thank you for your patch.
I think it's a good idea to store OS ifname in rte_eth_dev_info.

Could you please split generic declaration and pcap implementation in 2 
patches ?

We should maybe keep ifname as variable name (you are using host_ifname and 
iface_name).

-- 
Thomas

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [dpdk-dev] [PATCH] RFC: Introduce host_ifname field to struct rte_eth_dev_info
  2013-12-04 15:39 [dpdk-dev] [PATCH] RFC: Introduce host_ifname field to struct rte_eth_dev_info Mats Liljegren
  2014-01-02 13:51 ` Thomas Monjalon
@ 2014-01-02 16:36 ` Stephen Hemminger
  1 sibling, 0 replies; 3+ messages in thread
From: Stephen Hemminger @ 2014-01-02 16:36 UTC (permalink / raw)
  To: Mats Liljegren; +Cc: dev

On Wed, 4 Dec 2013 16:39:05 +0100
Mats Liljegren <liljegren.mats2@gmail.com> wrote:

> 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

interface name can be changed while application is running not sure
if you want to cache it! Ifindex can't change.

Also, if you use sysfs you can get/set irq_affinity based on PCI address.

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2014-01-02 16:40 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-12-04 15:39 [dpdk-dev] [PATCH] RFC: Introduce host_ifname field to struct rte_eth_dev_info Mats Liljegren
2014-01-02 13:51 ` Thomas Monjalon
2014-01-02 16:36 ` Stephen Hemminger

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).