[dpdk-dev] [PATCH v4 4/5] net/hns3: add Rx buffer size to Rx qinfo query

2020-09-05 Thread Chengchang Tang
Report hns3 PMD configured Rx buffer size in Rx queue information query.

Signed-off-by: Chengchang Tang 
Reviewed-by: Wei Hu (Xavier) 
---
 drivers/net/hns3/hns3_rxtx.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/hns3/hns3_rxtx.c b/drivers/net/hns3/hns3_rxtx.c
index fc1a256..d67c5ad 100644
--- a/drivers/net/hns3/hns3_rxtx.c
+++ b/drivers/net/hns3/hns3_rxtx.c
@@ -2830,6 +2830,8 @@ hns3_rxq_info_get(struct rte_eth_dev *dev, uint16_t 
queue_id,
qinfo->mp = rxq->mb_pool;
qinfo->nb_desc = rxq->nb_rx_desc;
qinfo->scattered_rx = dev->data->scattered_rx;
+   /* Report the HW Rx buffer length to user */
+   qinfo->rx_buf_size = rxq->rx_buf_len;

/*
 * If there are no available Rx buffer descriptors, incoming packets
--
2.7.4



[dpdk-dev] [PATCH v4 3/5] app/procinfo: add Rx buffer size to --show-port

2020-09-05 Thread Chengchang Tang
Add Rx buffer size to show_port function to display it in the port PMD
information so that the user can get the buffer length used by HW queue
of receiving packets.

Signed-off-by: Chengchang Tang 
---
 app/proc-info/main.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/app/proc-info/main.c b/app/proc-info/main.c
index abeca4a..e840dea 100644
--- a/app/proc-info/main.c
+++ b/app/proc-info/main.c
@@ -711,11 +711,13 @@ show_port(void)
if (ret == 0) {
printf("\t  -- queue %d rx scatter %d"
" descriptors %d"
+   " rx buffer size %d"
" offloads 0x%"PRIx64
" mempool socket %d\n",
j,
queue_info.scattered_rx,
queue_info.nb_desc,
+   queue_info.rx_buf_size,
queue_info.conf.offloads,
queue_info.mp->socket_id);
}
--
2.7.4



[dpdk-dev] [PATCH v4 0/5] add Rx buffer size for rxq info structure

2020-09-05 Thread Chengchang Tang
In common practice, PMD configure the Rx buffer size which indicate the
buffer length could be used for HW in receiving packets according to the
data room size of the object in mempool. But in fact, the final value is
related to the specifications of HW, and its values will affect the number
of fragments in receiving packets when scatter is enabled. By the way,
some PMDs may force to enable scatter when the MTU is bigger than the HW
Rx buffer size.

At present, we have no way to expose relevant information to upper layer
users. So, add a field named rx_buf_size in rte_eth_rxq_info to indicate
the buffer size used in receiving packets for HW. And this field is
optional, so there is no need to forcibly update all PMDs.

This patchset also update testpmd, proc-info tools and add hns3 PMD
implementation.

v4:
  - remove deprecation notice once changes applied

Chengchang Tang (5):
  ethdev: add a field for rxq info structure
  app/testpmd: add Rx buffer size display in queue info query
  app/procinfo: add Rx buffer size to --show-port
  net/hns3: add Rx buffer size to Rx qinfo query
  doc: remove rxq info structure deprecation notice

 app/proc-info/main.c | 2 ++
 app/test-pmd/config.c| 1 +
 doc/guides/rel_notes/deprecation.rst | 5 -
 drivers/net/hns3/hns3_rxtx.c | 2 ++
 lib/librte_ethdev/rte_ethdev.h   | 2 ++
 5 files changed, 7 insertions(+), 5 deletions(-)

--
2.7.4



[dpdk-dev] [PATCH v4 5/5] doc: remove rxq info structure deprecation notice

2020-09-05 Thread Chengchang Tang
The change has been applied, so remove the notice.

Signed-off-by: Chengchang Tang 
---
 doc/guides/rel_notes/deprecation.rst | 5 -
 1 file changed, 5 deletions(-)

diff --git a/doc/guides/rel_notes/deprecation.rst 
b/doc/guides/rel_notes/deprecation.rst
index 345c38d..b6d57b9 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -215,11 +215,6 @@ Deprecation Notices
   specified lengths into the buffers allocated from the specified
   memory pools. The backward compatibility to existing API is preserved.

-* ethdev: The ``struct rte_eth_rxq_info`` will be modified to include
-  a new optional field, indicating the buffer size used in receiving packets
-  for HW. This change is planned for 20.11. For more details:
-  https://mails.dpdk.org/archives/dev/2020-July/176135.html.
-
 * ethdev: ``rx_descriptor_done`` dev_ops and ``rte_eth_rx_descriptor_done``
   will be deprecated in 20.11 and will be removed in 21.11.
   Existing ``rte_eth_rx_descriptor_status`` and 
``rte_eth_tx_descriptor_status``
--
2.7.4



[dpdk-dev] [PATCH v4 1/5] ethdev: add a field for rxq info structure

2020-09-05 Thread Chengchang Tang
Add a field named rx_buf_size in rte_eth_rxq_info to indicate the buffer
size used in receiving packets for HW.

In this way, upper-layer users can get this information by calling
rte_eth_rx_queue_info_get.

Signed-off-by: Chengchang Tang 
Reviewed-by: Wei Hu (Xavier) 
Acked-by: Andrew Rybchenko 
---
 lib/librte_ethdev/rte_ethdev.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/lib/librte_ethdev/rte_ethdev.h b/lib/librte_ethdev/rte_ethdev.h
index 70295d7..859111a 100644
--- a/lib/librte_ethdev/rte_ethdev.h
+++ b/lib/librte_ethdev/rte_ethdev.h
@@ -1420,6 +1420,8 @@ struct rte_eth_rxq_info {
struct rte_eth_rxconf conf; /**< queue config parameters. */
uint8_t scattered_rx;   /**< scattered packets RX supported. */
uint16_t nb_desc;   /**< configured number of RXDs. */
+   /**< Buffer size used for HW when receive packets. */
+   uint16_t rx_buf_size;
 } __rte_cache_min_aligned;

 /**
--
2.7.4



[dpdk-dev] [PATCH v4 2/5] app/testpmd: add Rx buffer size display in queue info query

2020-09-05 Thread Chengchang Tang
Add Rx buffer size to queue info querry cmd so that the user can get the
buffer length used by HW queue for receiving packets.

Signed-off-by: Chengchang Tang 
Reviewed-by: Wei Hu (Xavier) 
---
 app/test-pmd/config.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index 30bee33..b432ac6 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -452,6 +452,7 @@ rx_queue_infos_display(portid_t port_id, uint16_t queue_id)
(qinfo.conf.rx_deferred_start != 0) ? "on" : "off");
printf("\nRX scattered packets: %s",
(qinfo.scattered_rx != 0) ? "on" : "off");
+   printf("\nRX buffer size: %hu", qinfo.rx_buf_size);
printf("\nNumber of RXDs: %hu", qinfo.nb_desc);

if (rte_eth_rx_burst_mode_get(port_id, queue_id, &mode) == 0)
--
2.7.4



[dpdk-dev] [PATCH 1/2] net/bnxt: remove logically dead code

2020-09-05 Thread wangyunjian
From: Yunjian Wang 

This patch removes logically dead code reported by coverity.

Coverity issue: 360824
Fixes: 6dc83230b43b ("net/bnxt: support port representor data path")
Cc: sta...@dpdk.org

Signed-off-by: Yunjian Wang 
---
 drivers/net/bnxt/bnxt_reps.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/net/bnxt/bnxt_reps.c b/drivers/net/bnxt/bnxt_reps.c
index 6fa9a30d2..e924025cf 100644
--- a/drivers/net/bnxt/bnxt_reps.c
+++ b/drivers/net/bnxt/bnxt_reps.c
@@ -44,8 +44,6 @@ bnxt_vfr_recv(uint16_t port_id, uint16_t queue_id, struct 
rte_mbuf *mbuf)
uint8_t que;
 
vfr_eth_dev = &rte_eth_devices[port_id];
-   if (!vfr_eth_dev)
-   return 1;
vfr_bp = vfr_eth_dev->data->dev_private;
/* If rxq_id happens to be > max rep_queue, use rxq0 */
que = queue_id < BNXT_MAX_VF_REP_RINGS ? queue_id : 0;
-- 
2.18.1




[dpdk-dev] [PATCH 0/2] fixes for bnxt driver

2020-09-05 Thread wangyunjian
From: Yunjian Wang 

This series include two fixes patches for bnxt driver.

Yunjian Wang (2):
  net/bnxt: remove logically dead code
  net/bnxt: fix a wrong use of rte_free when freeing mbuf

 drivers/net/bnxt/bnxt_reps.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

-- 
2.18.1




[dpdk-dev] [PATCH 2/2] net/bnxt: fix a wrong use of rte_free when freeing mbuf

2020-09-05 Thread wangyunjian
From: Yunjian Wang 

We should use rte_pktmbuf_free() instead of rte_free() to free the mbuf.

Fixes: 6dc83230b43b ("net/bnxt: support port representor data path")
Cc: sta...@dpdk.org

Signed-off-by: Yunjian Wang 
---
 drivers/net/bnxt/bnxt_reps.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/bnxt/bnxt_reps.c b/drivers/net/bnxt/bnxt_reps.c
index e924025cf..26bd0f626 100644
--- a/drivers/net/bnxt/bnxt_reps.c
+++ b/drivers/net/bnxt/bnxt_reps.c
@@ -61,7 +61,7 @@ bnxt_vfr_recv(uint16_t port_id, uint16_t queue_id, struct 
rte_mbuf *mbuf)
} else {
vfr_bp->rx_drop_bytes[que] += mbuf->pkt_len;
vfr_bp->rx_drop_pkts[que]++;
-   rte_free(mbuf); /* Representor Rx ring full, drop pkt */
+   rte_pktmbuf_free(mbuf); /* Representor Rx ring full, drop pkt */
}
 
return 0;
-- 
2.18.1




[dpdk-dev] [PATCH] crypto/dpaax_sec: fix a null pointer dereference after null check

2020-09-05 Thread wangyunjian
From: Yunjian Wang 

This patch fixes a null pointer dereference after null check detected by
coverity scan.

Coverity issue: 349904
Fixes: 6a0c9d364afc ("crypto/dpaax_sec: support HFN override")
Cc: sta...@dpdk.org

Signed-off-by: Yunjian Wang 
---
 drivers/crypto/dpaa_sec/dpaa_sec.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/crypto/dpaa_sec/dpaa_sec.c 
b/drivers/crypto/dpaa_sec/dpaa_sec.c
index c4339336d..fa42c9906 100644
--- a/drivers/crypto/dpaa_sec/dpaa_sec.c
+++ b/drivers/crypto/dpaa_sec/dpaa_sec.c
@@ -2949,7 +2949,8 @@ dpaa_sec_set_pdcp_session(struct rte_cryptodev *dev,
session->pdcp.hfn = pdcp_xform->hfn;
session->pdcp.hfn_threshold = pdcp_xform->hfn_threshold;
session->pdcp.hfn_ovd = pdcp_xform->hfn_ovrd;
-   session->pdcp.hfn_ovd_offset = cipher_xform->iv.offset;
+   if (cipher_xform)
+   session->pdcp.hfn_ovd_offset = cipher_xform->iv.offset;
 
rte_spinlock_lock(&dev_priv->lock);
for (i = 0; i < MAX_DPAA_CORES; i++) {
-- 
2.18.1




Re: [dpdk-dev] [PATCH v4 5/5] doc: remove rxq info structure deprecation notice

2020-09-05 Thread Thomas Monjalon
05/09/2020 11:07, Chengchang Tang:
> The change has been applied, so remove the notice.

It should be atomic with the patch doing the change,
i.e. you can squash.

I think the oneline patches in testpmd and procinfo
can probably be squashed with the ethdev patch as well.

Thanks




Re: [dpdk-dev] [PATCH v4 1/5] ethdev: add a field for rxq info structure

2020-09-05 Thread Stephen Hemminger
On Sat, 5 Sep 2020 17:07:30 +0800
Chengchang Tang  wrote:

> diff --git a/lib/librte_ethdev/rte_ethdev.h b/lib/librte_ethdev/rte_ethdev.h
> index 70295d7..859111a 100644
> --- a/lib/librte_ethdev/rte_ethdev.h
> +++ b/lib/librte_ethdev/rte_ethdev.h
> @@ -1420,6 +1420,8 @@ struct rte_eth_rxq_info {
>   struct rte_eth_rxconf conf; /**< queue config parameters. */
>   uint8_t scattered_rx;   /**< scattered packets RX supported. */
>   uint16_t nb_desc;   /**< configured number of RXDs. */
> + /**< Buffer size used for HW when receive packets. */
> + uint16_t rx_buf_size;

Minor suggestion.
If you shorten the comment (which is not that useful) and use the same
case, then it will fit on the same line and look like the rest of the code.

uint16_t rx_buf_size;  /**< hardware receive buffer size */


Re: [dpdk-dev] [PATCH V2 1/4] ethdev: fix compiling errors for per-queue statistics

2020-09-05 Thread Thomas Monjalon
04/09/2020 20:31, Ferruh Yigit:
> On 9/4/2020 12:32 PM, Min Hu (Connor) wrote:
> > From: Huisong Li 
> > 
> > Currently, only statistics of rx/tx queues with queue_id less than
> > RTE_ETHDEV_QUEUE_STAT_CNTRS can be displayed. If there is a certain
> > application scenario that it needs to use 256 or more than 256 queues
> > and display all statistics of rx/tx queue. At this moment, we have to
> > change the macro to be equaled to the queue number.
> > 
> > However, modifying the macro to be greater than 256 will trigger
> > many errors and warnings from test-pmd, PMD driver and librte_ethdev
> > during compiling dpdk project. But it is possible and permited that
> > rx/tx queue number is greater than 256 and all statistics of rx/tx
> > queue need to be displayed. In addition, the data type of rx/tx queue
> > number in rte_eth_dev_configure API is 'uint16_t'. So It is unreasonable
> > to use the 'uint8_t' type for variables that control which per-queue
> > statistics can be displayed.
> > 
> > Fixes: ed30d9b691b2 ("app/testpmd: add stats per queue")
> > Fixes: 09c7e63a71f9 ("net/memif: introduce memory interface PMD")
> > Fixes: abf7275bbaa2 ("ixgbe: move to drivers/net/")
> > Fixes: e6defdfddc3b ("net/igc: enable statistics")
> > Fixes: 2265e4b4e84b ("net/octeontx2: add basic stats operation")
> > Fixes: 6c3169a3dc04 ("virtio: move to drivers/net/")
> > Cc: sta...@dpdk.org
> > 
> > Signed-off-by: Huisong Li 
> > Signed-off-by: Min Hu (Connor) 
> > Reviewed-by: Wei Hu (Xavier) 
> > Reviewed-by: Dongdong Liu 
> 
> The patch mostly looks good and it enables build with
> 'RTE_ETHDEV_QUEUE_STAT_CNTRS' > 256.
> Only I put a comment for a testpmd change to enable the "set stat_qmap" 
> command
> for map value > 256.
> 
> 
> BUT there are many things to fix in the queue stats mapping, since you are
> already on it can you help on a few things on testpmd related to it, if you 
> have
> time for it?
> 
> 1) Getting queue stats shouldn't require stats mapping, it should be 
> controlled
> separately. Many PMDs doesn't require/do the stats mapping but they still can
> collect the per queue stats, which can be displayed independent from mapping.
> 
> 2) Even you map only one queue, while displaying stats it will display
> 'RTE_ETHDEV_QUEUE_STAT_CNTRS' queues, and when that number is high it makes 
> hard
> to see the actual interested values.
> If there is no mapping, it should display min(number_of_queues,
> RTE_ETHDEV_QUEUE_STAT_CNTRS).
> If there is mapping it should display queues that mapping done, this may 
> require
> adding a new 'active' field to 'struct queue_stats_mappings'.
> 
> 3) Why 'struct queue_stats_mappings' is cache aligned, is it really needed?
> 
> 4) The mapping arrays, 'tx_queue_stats_mappings_array' &
> 'rx_queue_stats_mappings_array' are global and their size is based on fixed 
> max
> port and queue size assumptions, can those mapping array be done per port and
> 'RTE_ETHDEV_QUEUE_STAT_CNTRS' size per port?

Yes there are a lot of things to review in this area.
For reference, the slides I presented last year:
https://www.dpdk.org/wp-content/uploads/sites/35/2019/10/WhichStandard.pdf

I think we should fix the xstats name "rx_q%u%s" to "rx_q%u_%s".




Re: [dpdk-dev] [PATCH v2] net: adjust the header length parse size

2020-09-05 Thread Stephen Hemminger
On Sat,  5 Sep 2020 11:06:46 +0800
Haiyue Wang  wrote:

> Align to the rte_mbuf's design about Tx header length data size for the
> header length parse result.
>   struct {
>   uint64_t   l2_len:7; /*88: 0  8 */
>   uint64_t   l3_len:9; /*88: 7  8 */
>   uint64_t   l4_len:8; /*88:16  8 */
>   uint64_t   tso_segsz:16; /*88:24  8 */
>   uint64_t   outer_l3_len:9;   /*88:40  8 */
>   uint64_t   outer_l2_len:7;   /*88:49  8 */
>   };
> 
> Now the IPv6 can support bigger extension header.
> 
> The below is the structure hole analysis result:
> 
> Before:
> struct rte_net_hdr_lens {
> uint8_tl2_len;   /* 0 1 */
> uint8_tl3_len;   /* 1 1 */
> uint8_tl4_len;   /* 2 1 */
> uint8_ttunnel_len;   /* 3 1 */
> uint8_tinner_l2_len; /* 4 1 */
> uint8_tinner_l3_len; /* 5 1 */
> uint8_tinner_l4_len; /* 6 1 */
> 
> /* size: 7, cachelines: 1, members: 7 */
> /* last cacheline: 7 bytes */
> };
> 
> Now:
> struct rte_net_hdr_lens {
> uint64_t   l2_len:7; /* 0: 0  8 */
> uint64_t   l3_len:9; /* 0: 7  8 */
> uint64_t   l4_len:8; /* 0:16  8 */
> uint64_t   tunnel_len:8; /* 0:24  8 */
> uint64_t   inner_l2_len:7;   /* 0:32  8 */
> uint64_t   inner_l3_len:9;   /* 0:39  8 */
> uint64_t   inner_l4_len:8;   /* 0:48  8 */
> 
> /* size: 8, cachelines: 1, members: 7 */
> /* bit_padding: 8 bits */
> /* last cacheline: 8 bytes */
> };
> 
> Signed-off-by: Haiyue Wang 

Bitfields are slow to access, compiler has to do mask/shift operations.
And there is no requirement that structure be the same size.

There is no requirement that fields be ordered the same as
the protocol header. Also tunnel length might get big.
Why not:

struct rte_net_hdr_lens {
uint8_t l2_len;
uint8_t inner_l2_len;
uint16_t l3_len;
uint16_t inner_l3_len;
uint16_t tunnel_len;
uint8_t l4_len;
uint8_t inner_l4_len;
};




Re: [dpdk-dev] [PATCH v4 3/5] app/procinfo: add Rx buffer size to --show-port

2020-09-05 Thread Stephen Hemminger
On Sat, 5 Sep 2020 17:07:32 +0800
Chengchang Tang  wrote:

>   printf("\t  -- queue %d rx scatter %d"
>   " descriptors %d"
> + " rx buffer size %d"
>   " offloads 0x%"PRIx64
>   " mempool socket %d\n",
>   j,
>   queue_info.scattered_rx,
>   queue_info.nb_desc,
> + queue_info.rx_buf_size,
>   queue_info.conf.offloads,
>   queue_info.mp->socket_id);
>   }

These should be using %u and need space after " for PRIx64
Why not:
printf("\t  -- queue %u rx scatter %u"
" descriptors %u"
" rx buffer size %u"
" offloads %#" PRIx64
" mempool socket %d\n",


[dpdk-dev] [PATCH 01/11] cpu_layout: refactor to meet python standards

2020-09-05 Thread Stephen Hemminger
Rearrange code to make it pass python lint.
This includes add a main function, docstring, and some
variable name changes.

Signed-off-by: Stephen Hemminger 
---
 usertools/cpu_layout.py | 145 +++-
 1 file changed, 85 insertions(+), 60 deletions(-)

diff --git a/usertools/cpu_layout.py b/usertools/cpu_layout.py
index 89a48cec463e..1e4577143ac5 100755
--- a/usertools/cpu_layout.py
+++ b/usertools/cpu_layout.py
@@ -2,67 +2,92 @@
 # SPDX-License-Identifier: BSD-3-Clause
 # Copyright(c) 2010-2014 Intel Corporation
 # Copyright(c) 2017 Cavium, Inc. All rights reserved.
+"""
+Show CPU layout
+"""
+SYS_DEVICES_CPU = "/sys/devices/system/cpu"
 
-import sys
-
-sockets = []
-cores = []
-core_map = {}
-base_path = "/sys/devices/system/cpu"
-fd = open("{}/kernel_max".format(base_path))
-max_cpus = int(fd.read())
-fd.close()
-for cpu in range(max_cpus + 1):
-try:
-fd = open("{}/cpu{}/topology/core_id".format(base_path, cpu))
-except IOError:
-continue
-except:
-break
-core = int(fd.read())
-fd.close()
-fd = open("{}/cpu{}/topology/physical_package_id".format(base_path, cpu))
-socket = int(fd.read())
-fd.close()
-if core not in cores:
-cores.append(core)
-if socket not in sockets:
-sockets.append(socket)
-key = (socket, core)
-if key not in core_map:
-core_map[key] = []
-core_map[key].append(cpu)
-
-print(format("=" * (47 + len(base_path
-print("Core and Socket Information (as reported by '{}')".format(base_path))
-print("{}\n".format("=" * (47 + len(base_path
-print("cores = ", cores)
-print("sockets = ", sockets)
-print("")
-
-max_processor_len = len(str(len(cores) * len(sockets) * 2 - 1))
-max_thread_count = len(list(core_map.values())[0])
-max_core_map_len = (max_processor_len * max_thread_count)  \
+
+def print_coremap(sockets, cores, core_map):
+'''print core, thread, socket mapping'''
+max_processor_len = len(str(len(cores) * len(sockets) * 2 - 1))
+max_thread_count = len(list(core_map.values())[0])
+max_core_map_len = (max_processor_len * max_thread_count)  \
   + len(", ") * (max_thread_count - 1) \
   + len('[]') + len('Socket ')
-max_core_id_len = len(str(max(cores)))
-
-output = " ".ljust(max_core_id_len + len('Core '))
-for s in sockets:
-output += " Socket %s" % str(s).ljust(max_core_map_len - len('Socket '))
-print(output)
-
-output = " ".ljust(max_core_id_len + len('Core '))
-for s in sockets:
-output += " ".ljust(max_core_map_len)
-output += " "
-print(output)
-
-for c in cores:
-output = "Core %s" % str(c).ljust(max_core_id_len)
-for s in sockets:
-if (s,c) in core_map:
-output += " " + str(core_map[(s, c)]).ljust(max_core_map_len)
-else:
-output += " " * (max_core_map_len + 1)
+
+max_core_id_len = len(str(max(cores)))
+
+output = " ".ljust(max_core_id_len + len('Core '))
+for socket in sockets:
+output += " Socket %s" % str(socket).ljust(max_core_map_len -
+   len('Socket '))
+print(output)
+
+output = " ".ljust(max_core_id_len + len('Core '))
+for socket in sockets:
+output += " ".ljust(max_core_map_len)
+output += " "
 print(output)
+
+for core in cores:
+output = "Core %s" % str(core).ljust(max_core_id_len)
+for socket in sockets:
+if (socket, core) in core_map:
+output += " " + str(core_map[(socket,
+  core)]).ljust(max_core_map_len)
+else:
+output += " " * (max_core_map_len + 1)
+print(output)
+
+
+def print_header(sockets, cores):
+'''print the core socket information header'''
+header_len = 47 + len(SYS_DEVICES_CPU)
+print(format("=" * header_len))
+print("Core and Socket Information (as reported by '{}')".format(
+SYS_DEVICES_CPU))
+print("{}\n".format("=" * header_len))
+print("cores = ", cores)
+print("sockets = ", sockets)
+print("")
+
+
+def main():
+'''program main function'''
+
+with open("{}/kernel_max".format(SYS_DEVICES_CPU)) as kernel_max:
+max_cpus = int(kernel_max.read())
+
+core_map = {}
+sockets = []
+cores = []
+
+for cpu in range(max_cpus + 1):
+topo_path = "{}/cpu{}/topology/".format(SYS_DEVICES_CPU, cpu)
+try:
+with open(topo_path + "core_id") as core_id:
+core = int(core_id.read())
+except FileNotFoundError:
+break
+except IOError:
+continue
+
+with open(topo_path + "physical_package_id") as package_id:
+socket = int(package_id.read())
+
+if core not in cores:
+cores.append(core)
+if socket not in sockets:
+sockets.append(socket)
+key = (socket, core)
+i

[dpdk-dev] [PATCH 02/11] dpdk-pmdinfo: replace string.split with split

2020-09-05 Thread Stephen Hemminger
In python3 the standard way to split strings is to use the
split() on the string object itself. The old way is broken
and would cause a traceback.

Signed-off-by: Stephen Hemminger 
---
 usertools/dpdk-pmdinfo.py | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/usertools/dpdk-pmdinfo.py b/usertools/dpdk-pmdinfo.py
index 16619827911a..7576a3313f36 100755
--- a/usertools/dpdk-pmdinfo.py
+++ b/usertools/dpdk-pmdinfo.py
@@ -11,7 +11,6 @@
 import io
 import os
 import platform
-import string
 import sys
 from elftools.common.exceptions import ELFError
 from elftools.common.py3compat import byte2int
@@ -229,7 +228,7 @@ def loadLocal(self):
 
 def search_file(filename, search_path):
 """ Given a search path, find file with requested name """
-for path in string.split(search_path, ":"):
+for path in search_path.split(':'):
 candidate = os.path.join(path, filename)
 if os.path.exists(candidate):
 return os.path.abspath(candidate)
-- 
2.27.0



[dpdk-dev] [PATCH 00/11] Python script updates

2020-09-05 Thread Stephen Hemminger
After writing the hugepages script, decided that the other python
scripts need a cleanup and refresh.  These changes apply after
Louise Kilheeney's patch to change to full Python 3 only.

Stephen Hemminger (11):
  cpu_layout: refactor to meet python standards
  dpdk-pmdinfo: replace string.split with split
  dpdk-pmdinfo: replace io.open with open
  dpdk-pmdinfo: remove dead code
  dpdk-pmdinfo: remove unnecessary paren and else
  dpdk-pmdinfo: replace is False and is True
  dpdk-pmdinfo: fix indentation
  dpdk-pmdinfo: replace deprecated optionparse with argparse
  dpdk-pmdinfo: do not use len(x) to test for empty
  dpdk-telemetry-client: fix some pylint warnings
  dpdk-devbind: use argparse instead of getopt

 usertools/cpu_layout.py| 145 -
 usertools/dpdk-devbind.py  | 196 +
 usertools/dpdk-pmdinfo.py  | 140 +
 usertools/dpdk-telemetry-client.py |  28 +++--
 4 files changed, 249 insertions(+), 260 deletions(-)

-- 
2.27.0



[dpdk-dev] [PATCH 04/11] dpdk-pmdinfo: remove dead code

2020-09-05 Thread Stephen Hemminger
The method loadLocal() is never called, and if it was it would
throw an exception because it calling readLocal() without a filename.

Pylint spotted this.

Signed-off-by: Stephen Hemminger 
---
 usertools/dpdk-pmdinfo.py | 8 
 1 file changed, 8 deletions(-)

diff --git a/usertools/dpdk-pmdinfo.py b/usertools/dpdk-pmdinfo.py
index 4fefdc83e583..9ee8fe9fa1ec 100755
--- a/usertools/dpdk-pmdinfo.py
+++ b/usertools/dpdk-pmdinfo.py
@@ -214,14 +214,6 @@ def readLocal(self, filename):
 self.contents = f.readlines()
 self.date = self.findDate(self.contents)
 
-def loadLocal(self):
-"""
-Loads database from local. If there is no file,
-it creates a new one from web
-"""
-self.date = idsfile[0].split("/")[1].split("-")[0]
-self.readLocal()
-
 
 # ===
 
-- 
2.27.0



[dpdk-dev] [PATCH 06/11] dpdk-pmdinfo: replace is False and is True

2020-09-05 Thread Stephen Hemminger
Code reads better if unnecessary comparison with False and True
is not used.

Signed-off-by: Stephen Hemminger 
---
 usertools/dpdk-pmdinfo.py | 24 
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/usertools/dpdk-pmdinfo.py b/usertools/dpdk-pmdinfo.py
index 32f8a82519fb..7c27a91182e4 100755
--- a/usertools/dpdk-pmdinfo.py
+++ b/usertools/dpdk-pmdinfo.py
@@ -367,7 +367,7 @@ def search_for_autoload_path(self):
   ":/usr/lib64:/lib64:/usr/lib:/lib")
 if library is None:
 return (None, None)
-if raw_output is False:
+if not raw_output:
 print("Scanning for autoload path in %s" % library)
 scanfile = open(library, 'rb')
 scanelf = ReadElf(scanfile, sys.stdout)
@@ -443,7 +443,7 @@ def process_dt_needed_entries(self):
   runpath + ":" + ldlibpath +
   ":/usr/lib64:/lib64:/usr/lib:/lib")
 if library is not None:
-if raw_output is False:
+if not raw_output:
 print("Scanning %s for pmd information" % library)
 with open(library, 'rb') as file:
 try:
@@ -473,7 +473,7 @@ def force_bytes(s):
 def scan_autoload_path(autoload_path):
 global raw_output
 
-if os.path.exists(autoload_path) is False:
+if not os.path.exists(autoload_path):
 return
 
 try:
@@ -497,7 +497,7 @@ def scan_autoload_path(autoload_path):
 # No permission to read the file, skip it
 continue
 
-if raw_output is False:
+if not raw_output:
 print("Hw Support for library %s" % d)
 readelf.display_pmd_info_strings(".rodata")
 file.close()
@@ -510,8 +510,8 @@ def scan_for_autoload_pmds(dpdk_path):
 """
 global raw_output
 
-if os.path.isfile(dpdk_path) is False:
-if raw_output is False:
+if not os.path.isfile(dpdk_path):
+if not raw_output:
 print("Must specify a file name")
 return
 
@@ -519,22 +519,22 @@ def scan_for_autoload_pmds(dpdk_path):
 try:
 readelf = ReadElf(file, sys.stdout)
 except ElfError:
-if raw_output is False:
+if not raw_output:
 print("Unable to parse %s" % file)
 return
 
 (autoload_path, scannedfile) = readelf.search_for_autoload_path()
 if not autoload_path:
-if raw_output is False:
+if not raw_output:
 print("No autoload path configured in %s" % dpdk_path)
 return
-if raw_output is False:
+if not raw_output:
 if scannedfile is None:
 scannedfile = dpdk_path
 print("Found autoload path %s in %s" % (autoload_path, scannedfile))
 
 file.close()
-if raw_output is False:
+if not raw_output:
 print("Discovered Autoload HW Support:")
 scan_autoload_path(autoload_path)
 return
@@ -593,14 +593,14 @@ def main(stream=None):
 optparser.print_usage()
 exit(1)
 
-if options.pdir is True:
+if options.pdir:
 exit(scan_for_autoload_pmds(args[0]))
 
 ldlibpath = os.environ.get('LD_LIBRARY_PATH')
 if ldlibpath is None:
 ldlibpath = ""
 
-if os.path.exists(args[0]) is True:
+if os.path.exists(args[0]):
 myelffile = args[0]
 else:
 myelffile = search_file(
-- 
2.27.0



[dpdk-dev] [PATCH 08/11] dpdk-pmdinfo: replace deprecated optparse with argparse

2020-09-05 Thread Stephen Hemminger
The optparse module is deprecated and replaced with new argparse.
The code now enforces the rule that only one of the output formats
can be specified: raw or json.

Signed-off-by: Stephen Hemminger 
---
 usertools/dpdk-pmdinfo.py | 70 ++-
 1 file changed, 32 insertions(+), 38 deletions(-)

diff --git a/usertools/dpdk-pmdinfo.py b/usertools/dpdk-pmdinfo.py
index d72feb308a6c..d746348f1415 100755
--- a/usertools/dpdk-pmdinfo.py
+++ b/usertools/dpdk-pmdinfo.py
@@ -11,10 +11,11 @@
 import os
 import platform
 import sys
+import argparse
 from elftools.common.exceptions import ELFError
 from elftools.common.py3compat import byte2int
 from elftools.elf.elffile import ELFFile
-from optparse import OptionParser
+
 
 # For running from development directory. It should take precedence over the
 # installed pyelftools.
@@ -555,56 +556,49 @@ def main(stream=None):
 if not os.path.exists(pcifile_default):
 pcifile_default = "/usr/share/misc/pci_vendors"
 
-optparser = OptionParser(
-usage='usage: %prog [-hrtp] [-d ',
-description="Dump pmd hardware support info",
-add_help_option=True)
-optparser.add_option('-r', '--raw',
- action='store_true', dest='raw_output',
- help='Dump raw json strings')
-optparser.add_option("-d", "--pcidb", dest="pcifile",
- help="specify a pci database "
-  "to get vendor names from",
- default=pcifile_default, metavar="FILE")
-optparser.add_option("-t", "--table", dest="tblout",
- help="output information on hw support as a "
-  "hex table",
- action='store_true')
-optparser.add_option("-p", "--plugindir", dest="pdir",
- help="scan dpdk for autoload plugins",
- action='store_true')
-
-options, args = optparser.parse_args()
-
-if options.raw_output:
+parser = argparse.ArgumentParser(
+usage='usage: %(prog)s [-hrtp] [-d ] elf_file',
+description="Dump pmd hardware support info")
+group = parser.add_mutually_exclusive_group()
+group.add_argument('-r', '--raw',
+   action='store_true', dest='raw_output',
+   help='dump raw json strings')
+group.add_argument("-t", "--table", dest="tblout",
+   help="output information on hw support as a hex table",
+   action='store_true')
+parser.add_argument("-d", "--pcidb", dest="pcifile",
+help="specify a pci database to get vendor names from",
+default=pcifile_default, metavar="FILE")
+parser.add_argument("-p", "--plugindir", dest="pdir",
+help="scan dpdk for autoload plugins",
+action='store_true')
+parser.add_argument("elf_file", help="driver shared object file")
+args = parser.parse_args()
+
+if args.raw_output:
 raw_output = True
 
-if options.pcifile:
-pcidb = PCIIds(options.pcifile)
+if args.tblout:
+args.pcifile = None
+
+if args.pcifile:
+pcidb = PCIIds(args.pcifile)
 if pcidb is None:
 print("Pci DB file not found")
 exit(1)
 
-if options.tblout:
-options.pcifile = None
-pcidb = None
-
-if len(args) == 0:
-optparser.print_usage()
-exit(1)
-
-if options.pdir:
+if args.pdir:
 exit(scan_for_autoload_pmds(args[0]))
 
 ldlibpath = os.environ.get('LD_LIBRARY_PATH')
 if ldlibpath is None:
 ldlibpath = ""
 
-if os.path.exists(args[0]):
-myelffile = args[0]
+if os.path.exists(args.elf_file):
+myelffile = args.elf_file
 else:
-myelffile = search_file(
-args[0], ldlibpath + ":/usr/lib64:/lib64:/usr/lib:/lib")
+myelffile = search_file(args.elf_file,
+ldlibpath + ":/usr/lib64:/lib64:/usr/lib:/lib")
 
 if myelffile is None:
 print("File not found")
-- 
2.27.0



[dpdk-dev] [PATCH 03/11] dpdk-pmdinfo: replace io.open with open

2020-09-05 Thread Stephen Hemminger
The builtin open() is the recommended approach in python3.
io.open was for compatiablity with older versions.

Signed-off-by: Stephen Hemminger 
---
 usertools/dpdk-pmdinfo.py | 13 ++---
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/usertools/dpdk-pmdinfo.py b/usertools/dpdk-pmdinfo.py
index 7576a3313f36..4fefdc83e583 100755
--- a/usertools/dpdk-pmdinfo.py
+++ b/usertools/dpdk-pmdinfo.py
@@ -8,7 +8,6 @@
 #
 # -
 import json
-import io
 import os
 import platform
 import sys
@@ -211,7 +210,7 @@ def readLocal(self, filename):
 """
 Reads the local file
 """
-with io.open(filename, 'r', encoding='utf-8') as f:
+with open(filename, 'r', encoding='utf-8') as f:
 self.contents = f.readlines()
 self.date = self.findDate(self.contents)
 
@@ -380,7 +379,7 @@ def search_for_autoload_path(self):
 return (None, None)
 if raw_output is False:
 print("Scanning for autoload path in %s" % library)
-scanfile = io.open(library, 'rb')
+scanfile = open(library, 'rb')
 scanelf = ReadElf(scanfile, sys.stdout)
 except AttributeError:
 # Not a dynamic binary
@@ -456,7 +455,7 @@ def process_dt_needed_entries(self):
 if library is not None:
 if raw_output is False:
 print("Scanning %s for pmd information" % library)
-with io.open(library, 'rb') as file:
+with open(library, 'rb') as file:
 try:
 libelf = ReadElf(file, sys.stdout)
 except ELFError:
@@ -499,7 +498,7 @@ def scan_autoload_path(autoload_path):
 scan_autoload_path(dpath)
 if os.path.isfile(dpath):
 try:
-file = io.open(dpath, 'rb')
+file = open(dpath, 'rb')
 readelf = ReadElf(file, sys.stdout)
 except ELFError:
 # this is likely not an elf file, skip it
@@ -526,7 +525,7 @@ def scan_for_autoload_pmds(dpdk_path):
 print("Must specify a file name")
 return
 
-file = io.open(dpdk_path, 'rb')
+file = open(dpdk_path, 'rb')
 try:
 readelf = ReadElf(file, sys.stdout)
 except ElfError:
@@ -621,7 +620,7 @@ def main(stream=None):
 print("File not found")
 sys.exit(1)
 
-with io.open(myelffile, 'rb') as file:
+with open(myelffile, 'rb') as file:
 try:
 readelf = ReadElf(file, sys.stdout)
 readelf.process_dt_needed_entries()
-- 
2.27.0



[dpdk-dev] [PATCH 09/11] dpdk-pmdinfo: do not use len(x) to test for empty

2020-09-05 Thread Stephen Hemminger
This fixes the following python lint warnings.
usertools/dpdk-pmdinfo.py:188:11: C1801: Do not use `len(SEQUENCE)` to 
determine if a sequence is empty (len-as-condition)
usertools/dpdk-pmdinfo.py:196:21: C1801: Do not use `len(SEQUENCE)` to 
determine if a sequence is empty (len-as-condition)
usertools/dpdk-pmdinfo.py:302:11: C1801: Do not use `len(SEQUENCE)` to 
determine if a sequence is empty (len-as-condition)

Signed-off-by: Stephen Hemminger 
---
 usertools/dpdk-pmdinfo.py | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/usertools/dpdk-pmdinfo.py b/usertools/dpdk-pmdinfo.py
index d746348f1415..632271e2f1d2 100755
--- a/usertools/dpdk-pmdinfo.py
+++ b/usertools/dpdk-pmdinfo.py
@@ -185,7 +185,7 @@ def findDate(self, content):
 return None
 
 def parse(self):
-if len(self.contents) < 1:
+if not len(self.contents):
 print("data/%s-pci.ids not found" % self.date)
 else:
 vendorID = ""
@@ -193,7 +193,7 @@ def parse(self):
 for l in self.contents:
 if l[0] == "#":
 continue
-elif len(l.strip()) == 0:
+elif not l.strip():
 continue
 else:
 if l.find("\t\t") == 0:
@@ -299,7 +299,7 @@ def parse_pmd_info_string(self, mystring):
 except KeyError:
 continue
 
-if len(pmdinfo["pci_ids"]) != 0:
+if pmdinfo["pci_ids"]:
 print("PMD HW SUPPORT:")
 if pcidb is not None:
 self.pretty_print_pmdinfo(pmdinfo)
-- 
2.27.0



[dpdk-dev] [PATCH 07/11] dpdk-pmdinfo: fix indentation

2020-09-05 Thread Stephen Hemminger
This fixes indentation warnings from pylint.

Signed-off-by: Stephen Hemminger 
---
 usertools/dpdk-pmdinfo.py | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/usertools/dpdk-pmdinfo.py b/usertools/dpdk-pmdinfo.py
index 7c27a91182e4..d72feb308a6c 100755
--- a/usertools/dpdk-pmdinfo.py
+++ b/usertools/dpdk-pmdinfo.py
@@ -323,7 +323,7 @@ def display_pmd_info_strings(self, section_spec):
 
 while dataptr < len(data):
 while (dataptr < len(data) and
-not 32 <= byte2int(data[dataptr]) <= 127):
+   not 32 <= byte2int(data[dataptr]) <= 127):
 dataptr += 1
 
 if dataptr >= len(data):
@@ -389,7 +389,7 @@ def search_for_autoload_path(self):
 
 while dataptr < len(data):
 while (dataptr < len(data) and
-not 32 <= byte2int(data[dataptr]) <= 127):
+   not 32 <= byte2int(data[dataptr]) <= 127):
 dataptr += 1
 
 if dataptr >= len(data):
-- 
2.27.0



[dpdk-dev] [PATCH 05/11] dpdk-pmdinfo: remove unnecessary paren and else

2020-09-05 Thread Stephen Hemminger
Python lint complains:
usertools/dpdk-pmdinfo.py:303:0: C0325: Unnecessary parens after 'if' keyword 
(superfluous-parens)
usertools/dpdk-pmdinfo.py:328:0: C0325: Unnecessary parens after 'not' keyword 
(superfluous-parens)
usertools/dpdk-pmdinfo.py:341:0: C0325: Unnecessary parens after 'if' keyword 
(superfluous-parens)
usertools/dpdk-pmdinfo.py:394:0: C0325: Unnecessary parens after 'not' keyword 
(superfluous-parens)
usertools/dpdk-pmdinfo.py:407:0: C0325: Unnecessary parens after 'if' keyword 
(superfluous-parens)
usertools/dpdk-pmdinfo.py:515:0: C0325: Unnecessary parens after 'if' keyword 
(superfluous-parens)
usertools/dpdk-pmdinfo.py:530:0: C0325: Unnecessary parens after 'if' keyword 
(superfluous-parens)
usertools/dpdk-pmdinfo.py:533:0: C0325: Unnecessary parens after 'if' keyword 
(superfluous-parens)
usertools/dpdk-pmdinfo.py:534:0: C0325: Unnecessary parens after 'if' keyword 
(superfluous-parens)
usertools/dpdk-pmdinfo.py:539:0: C0325: Unnecessary parens after 'if' keyword 
(superfluous-parens)
usertools/dpdk-pmdinfo.py:594:0: C0325: Unnecessary parens after 'if' keyword 
(superfluous-parens)
usertools/dpdk-pmdinfo.py:602:0: C0325: Unnecessary parens after 'if' keyword 
(superfluous-parens)
usertools/dpdk-pmdinfo.py:605:0: C0325: Unnecessary parens after 'if' keyword 
(superfluous-parens)
usertools/dpdk-pmdinfo.py:611:0: C0325: Unnecessary parens after 'if' keyword 
(superfluous-parens)
usertools/dpdk-pmdinfo.py:110:12: R1705: Unnecessary "else" after "return" 
(no-else-return)
usertools/dpdk-pmdinfo.py:254:12: R1705: Unnecessary "else" after "return" 
(no-else-return)

Signed-off-by: Stephen Hemminger 
---
 usertools/dpdk-pmdinfo.py | 34 --
 1 file changed, 16 insertions(+), 18 deletions(-)

diff --git a/usertools/dpdk-pmdinfo.py b/usertools/dpdk-pmdinfo.py
index 9ee8fe9fa1ec..32f8a82519fb 100755
--- a/usertools/dpdk-pmdinfo.py
+++ b/usertools/dpdk-pmdinfo.py
@@ -109,8 +109,7 @@ def find_subid(self, subven, subdev):
 except:
 if (subven == "" and subdev == ""):
 return SubDevice("", "", "(All Subdevices)")
-else:
-return SubDevice(subven, subdev, "(Unknown Subdevice)")
+return SubDevice(subven, subdev, "(Unknown Subdevice)")
 
 
 class SubDevice:
@@ -253,8 +252,7 @@ def _section_from_spec(self, spec):
 num = int(spec)
 if num < self.elffile.num_sections():
 return self.elffile.get_section(num)
-else:
-return None
+return None
 except ValueError:
 # Not a number. Must be a name then
 section = self.elffile.get_section_by_name(force_unicode(spec))
@@ -300,7 +298,7 @@ def parse_pmd_info_string(self, mystring):
 except KeyError:
 continue
 
-if (len(pmdinfo["pci_ids"]) != 0):
+if len(pmdinfo["pci_ids"]) != 0:
 print("PMD HW SUPPORT:")
 if pcidb is not None:
 self.pretty_print_pmdinfo(pmdinfo)
@@ -325,7 +323,7 @@ def display_pmd_info_strings(self, section_spec):
 
 while dataptr < len(data):
 while (dataptr < len(data) and
-not (32 <= byte2int(data[dataptr]) <= 127)):
+not 32 <= byte2int(data[dataptr]) <= 127):
 dataptr += 1
 
 if dataptr >= len(data):
@@ -338,7 +336,7 @@ def display_pmd_info_strings(self, section_spec):
 # pyelftools may return byte-strings, force decode them
 mystring = force_unicode(data[dataptr:endptr])
 rc = mystring.find("PMD_INFO_STRING")
-if (rc != -1):
+if rc != -1:
 self.parse_pmd_info_string(mystring)
 
 dataptr = endptr
@@ -391,7 +389,7 @@ def search_for_autoload_path(self):
 
 while dataptr < len(data):
 while (dataptr < len(data) and
-not (32 <= byte2int(data[dataptr]) <= 127)):
+not 32 <= byte2int(data[dataptr]) <= 127):
 dataptr += 1
 
 if dataptr >= len(data):
@@ -404,7 +402,7 @@ def search_for_autoload_path(self):
 # pyelftools may return byte-strings, force decode them
 mystring = force_unicode(data[dataptr:endptr])
 rc = mystring.find("DPDK_PLUGIN_PATH")
-if (rc != -1):
+if rc != -1:
 rc = mystring.find("=")
 return (mystring[rc + 1:], library)
 
@@ -512,7 +510,7 @@ def scan_for_autoload_pmds(dpdk_path):
 """
 global raw_output
 
-if (os.path.isfile(dpdk_path) is False):
+if os.path.isfile(dpdk_path) is False:
 if raw_output is False:
 print("Must specify a file name")
 return
@@ -527,16 +525,16 @@ def scan_for_autoload_pmds(dpdk_path):
 
 (autoload_path, scannedfile) = readelf.search_for_autoload_path()
 if not autoload_path:
-if (raw_o

[dpdk-dev] [PATCH 10/11] dpdk-telemetry-client: fix some pylint warnings

2020-09-05 Thread Stephen Hemminger
Convert comments to docstrings as appropriate.
Remove unnecessary paren in if statement.
Remove extra whitespace after print.

Signed-off-by: Stephen Hemminger 
---
 usertools/dpdk-telemetry-client.py | 28 ++--
 1 file changed, 18 insertions(+), 10 deletions(-)

diff --git a/usertools/dpdk-telemetry-client.py 
b/usertools/dpdk-telemetry-client.py
index fa599046a46b..7a22d1b99864 100755
--- a/usertools/dpdk-telemetry-client.py
+++ b/usertools/dpdk-telemetry-client.py
@@ -32,7 +32,8 @@ def __del__(self):
 
 class Client:
 
-def __init__(self): # Creates a client instance
+def __init__(self):
+''' Creates a client instance '''
 self.socket = Socket()
 self.file_path = None
 self.choice = None
@@ -45,16 +46,18 @@ def __del__(self):
 except:
 print("Error - Client could not be destroyed")
 
-def getFilepath(self, file_path): # Gets arguments from Command-Line and 
assigns to instance of client
+def getFilepath(self, file_path):
+'''Gets arguments from Command-Line and assigns to instance of 
client'''
 self.file_path = file_path
 
-def register(self): # Connects a client to DPDK-instance
+def register(self):
+'''Connects a client to DPDK-instance'''
 if os.path.exists(self.file_path):
 os.unlink(self.file_path)
 try:
 self.socket.recv_fd.bind(self.file_path)
 except socket.error as msg:
-print ("Error - Socket binding error: " + str(msg) + "\n")
+print("Error - Socket binding error: " + str(msg) + "\n")
 self.socket.recv_fd.settimeout(2)
 self.socket.send_fd.connect("/var/run/dpdk/rte/telemetry")
 JSON = (API_REG + self.file_path + "\"}}")
@@ -63,16 +66,19 @@ def register(self): # Connects a client to DPDK-instance
 self.socket.recv_fd.listen(1)
 self.socket.client_fd = self.socket.recv_fd.accept()[0]
 
-def unregister(self): # Unregister a given client
+def unregister(self):
+''' Unregister a given client '''
 self.socket.client_fd.send((API_UNREG + self.file_path + 
"\"}}").encode())
 self.socket.client_fd.close()
 
-def requestMetrics(self): # Requests metrics for given client
+def requestMetrics(self):
+''' Requests metrics for given client '''
 self.socket.client_fd.send(METRICS_REQ.encode())
 data = self.socket.client_fd.recv(BUFFER_SIZE).decode()
 print("\nResponse: \n", data)
 
-def repeatedlyRequestMetrics(self, sleep_time): # Recursively requests 
metrics for given client
+def repeatedlyRequestMetrics(self, sleep_time):
+''' Recursively requests metrics for given client '''
 print("\nPlease enter the number of times you'd like to continuously 
request Metrics:")
 n_requests = int(input("\n:"))
 print("\033[F") #Removes the user input from screen, cleans it up
@@ -81,12 +87,14 @@ def repeatedlyRequestMetrics(self, sleep_time): # 
Recursively requests metrics f
 self.requestMetrics()
 time.sleep(sleep_time)
 
-def requestGlobalMetrics(self): #Requests global metrics for given client
+def requestGlobalMetrics(self):
+''' Requests global metrics for given client '''
 self.socket.client_fd.send(GLOBAL_METRICS_REQ.encode())
 data = self.socket.client_fd.recv(BUFFER_SIZE).decode()
 print("\nResponse: \n", data)
 
-def interactiveMenu(self, sleep_time): # Creates Interactive menu within 
the script
+def interactiveMenu(self, sleep_time):
+''' Creates Interactive menu within the script '''
 while self.choice != 4:
 print("\nOptions Menu")
 print("[1] Send for Metrics for all ports")
@@ -116,7 +124,7 @@ def interactiveMenu(self, sleep_time): # Creates 
Interactive menu within the scr
 
 sleep_time = 1
 file_path = ""
-if (len(sys.argv) == 2):
+if len(sys.argv) == 2:
 file_path = sys.argv[1]
 else:
 print("Warning - No filepath passed, using default (" + DEFAULT_FP + 
").")
-- 
2.27.0



[dpdk-dev] [PATCH 11/11] dpdk-devbind: use argparse instead of getopt

2020-09-05 Thread Stephen Hemminger
Using the python standard argument parser instead of C library
style getopt gives a number of advantages such as checking
for conflicting arguments, restricting choices, and automatically
generating help messages.

The result is similar to the original the only visible change
is that some of the help messages are now less wordy.

Signed-off-by: Stephen Hemminger 
---
 usertools/dpdk-devbind.py | 196 +-
 1 file changed, 85 insertions(+), 111 deletions(-)

diff --git a/usertools/dpdk-devbind.py b/usertools/dpdk-devbind.py
index bcdc5da881d9..33d3ef798f7d 100755
--- a/usertools/dpdk-devbind.py
+++ b/usertools/dpdk-devbind.py
@@ -5,8 +5,8 @@
 
 import sys
 import os
-import getopt
 import subprocess
+import argparse
 from os.path import exists, abspath, dirname, basename
 
 # The PCI base class for all devices
@@ -72,76 +72,6 @@
 args = []
 
 
-def usage():
-'''Print usage information for the program'''
-argv0 = basename(sys.argv[0])
-print("""
-Usage:
---
-
- %(argv0)s [options] DEVICE1 DEVICE2 
-
-where DEVICE1, DEVICE2 etc, are specified via PCI "domain:bus:slot.func" syntax
-or "bus:slot.func" syntax. For devices bound to Linux kernel drivers, they may
-also be referred to by Linux interface name e.g. eth0, eth1, em0, em1, etc.
-
-Options:
---help, --usage:
-Display usage information and quit
-
--s, --status:
-Print the current status of all known network, crypto, event
-and mempool devices.
-For each device, it displays the PCI domain, bus, slot and function,
-along with a text description of the device. Depending upon whether the
-device is being used by a kernel driver, the igb_uio driver, or no
-driver, other relevant information will be displayed:
-* the Linux interface name e.g. if=eth0
-* the driver being used e.g. drv=igb_uio
-* any suitable drivers not currently using that device
-e.g. unused=igb_uio
-NOTE: if this flag is passed along with a bind/unbind option, the
-status display will always occur after the other operations have taken
-place.
-
---status-dev:
-Print the status of given device group. Supported device groups are:
-"net", "baseband", "crypto", "event", "mempool" and "compress"
-
--b driver, --bind=driver:
-Select the driver to use or \"none\" to unbind the device
-
--u, --unbind:
-Unbind a device (Equivalent to \"-b none\")
-
---force:
-By default, network devices which are used by Linux - as indicated by
-having routes in the routing table - cannot be modified. Using the
---force flag overrides this behavior, allowing active links to be
-forcibly unbound.
-WARNING: This can lead to loss of network connection and should be used
-with caution.
-
-Examples:
--
-
-To display current device status:
-%(argv0)s --status
-
-To display current network device status:
-%(argv0)s --status-dev net
-
-To bind eth1 from the current driver and move to use igb_uio
-%(argv0)s --bind=igb_uio eth1
-
-To unbind :01:00.0 from using any driver
-%(argv0)s -u :01:00.0
-
-To bind :02:00.0 and :02:00.1 to the ixgbe kernel driver
-%(argv0)s -b ixgbe 02:00.0 02:00.1
-
-""" % locals())  # replace items from local variables
-
 # check if a specific kernel module is loaded
 def module_is_loaded(module):
 global loaded_modules
@@ -642,38 +572,93 @@ def parse_args():
 global status_dev
 global force_flag
 global args
-if len(sys.argv) <= 1:
-usage()
-sys.exit(0)
 
-try:
-opts, args = getopt.getopt(sys.argv[1:], "b:us",
-   ["help", "usage", "status", "status-dev=",
-"force", "bind=", "unbind", ])
-except getopt.GetoptError as error:
-print(str(error))
-print("Run '%s --usage' for further information" % sys.argv[0])
+parser = argparse.ArgumentParser(
+description='Utility to bind and unbind devices from Linux kernel',
+formatter_class=argparse.RawDescriptionHelpFormatter,
+epilog="""
+Examples:
+-
+
+To display current device status:
+%(prog)s --status
+
+To display current network device status:
+%(prog)s --status-dev net
+
+To bind eth1 from the current driver and move to use vfio-pci
+%(prog)s --bind=vfio-pci eth1
+
+To unbind :01:00.0 from using any driver
+%(prog)s -u :01:00.0
+
+To bind :02:00.0 and :02:00.1 to the ixgbe kernel driver
+%(prog)s -b ixgbe 02:00.0 02:00.1
+""")
+
+parser.add_argument(
+'-s',
+'--status',
+action='store_true',
+help="Print the current status of all known devices.")
+parser.add_argument(
+'--status-dev',
+help="Print the status of given device group.",
+   

[dpdk-dev] [PATCH] doc/devbind: remove references to igb_uio

2020-09-05 Thread Stephen Hemminger
We should be encouraging the use of vfio_pci for developers, not telling
them to use igb_uio.

Also fix typo where .py suffix is visible in document.

Signed-off-by: Stephen Hemminger 
---
 doc/guides/tools/devbind.rst | 20 ++--
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/doc/guides/tools/devbind.rst b/doc/guides/tools/devbind.rst
index a2910e103aab..52690f018648 100644
--- a/doc/guides/tools/devbind.rst
+++ b/doc/guides/tools/devbind.rst
@@ -30,11 +30,11 @@ OPTIONS
 Print the current status of all known network interfaces.
 For each device, it displays the PCI domain, bus, slot and function,
 along with a text description of the device. Depending upon whether the
-device is being used by a kernel driver, the ``igb_uio`` driver, or no
+device is being used by a kernel driver, the ``vfio_pci`` driver, or no
 driver, other relevant information will be displayed:
 - the Linux interface name e.g. ``if=eth0``
-- the driver being used e.g. ``drv=igb_uio``
-- any suitable drivers not currently using that device e.g. 
``unused=igb_uio``
+- the driver being used e.g. ``drv=vfio_pci``
+- any suitable drivers not currently using that device e.g. 
``unused=vfio_pci``
 NOTE: if this flag is passed along with a bind/unbind option, the
 status display will always occur after the other operations have taken
 place.
@@ -69,7 +69,7 @@ OPTIONS
 
 .. warning::
 
-While any user can run the ``dpdk-devbind.py`` script to view the status 
of the network ports,
+While any user can run the ``dpdk-devbind`` script to view the status of 
the network ports,
 binding or unbinding network ports requires root privileges.
 
 
@@ -80,9 +80,9 @@ To display current device status::
 
dpdk-devbind --status
 
-To bind eth1 from the current driver and move to use igb_uio::
+To bind eth1 from the current driver and move to use vfio_pci::
 
-   dpdk-devbind --bind=igb_uio eth1
+   dpdk-devbind --bind=vfio_pci eth1
 
 To unbind :01:00.0 from using any driver::
 
@@ -92,7 +92,7 @@ To bind :02:00.0 and :02:00.1 to the ixgbe kernel 
driver::
 
dpdk-devbind -b ixgbe 02:00.0 02:00.1
 
-To check status of all network ports, assign one to the igb_uio driver and 
check status again::
+To check status of all network ports, assign one to the vfio_pci driver and 
check status again::
 
# Check the status of the available devices.
dpdk-devbind --status
@@ -105,12 +105,12 @@ To check status of all network ports, assign one to the 
igb_uio driver and check
:0a:00.0 '82599ES 10-Gigabit' if=eth2 drv=ixgbe unused=
 
 
-   # Bind the device to igb_uio.
-   sudo dpdk-devbind -b igb_uio :0a:00.0
+   # Bind the device to vfio_pci.
+   sudo dpdk-devbind -b vfio_pci :0a:00.0
 
 
# Recheck the status of the devices.
dpdk-devbind --status
Network devices using DPDK-compatible driver

-   :0a:00.0 '82599ES 10-Gigabit' drv=igb_uio unused=
+   :0a:00.0 '82599ES 10-Gigabit' drv=vfio_pci unused=
-- 
2.27.0



[dpdk-dev] [PATCH] doc/flow-perf: fix section headings

2020-09-05 Thread Stephen Hemminger
The flow-perf documentation was using multiple section headings
in one document. This caused the documentation tree display in
index to make it appear as multiple pages rather than sub-sections
in one page.

Change to use subsections and subsubsections.

Fixes: bf3688f1e816 ("app/flow-perf: add insertion rate calculation")
Cc: wis...@mellanox.com
Signed-off-by: Stephen Hemminger 
---
 doc/guides/tools/flow-perf.rst | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/doc/guides/tools/flow-perf.rst b/doc/guides/tools/flow-perf.rst
index cdedaf9a97d4..247dcf26703e 100644
--- a/doc/guides/tools/flow-perf.rst
+++ b/doc/guides/tools/flow-perf.rst
@@ -18,7 +18,7 @@ give different flow each time, and all other items will have 
open masks.
 
 
 Known Limitations
-=
+-
 
 The current version has limitations which can be removed in future:
 
@@ -33,7 +33,7 @@ The app supports single and multi core performance 
measurements.
 
 
 Compiling the Application
-=
+-
 
 The ``test-flow-perf`` application is compiled as part of the main compilation
 of the DPDK libraries and tools.
@@ -42,10 +42,10 @@ Refer to the DPDK Getting Started Guides for details.
 
 
 Running the Application
-===
+---
 
 EAL Command-line Options
-
+
 
 Please refer to :doc:`EAL parameters (Linux) 
<../linux_gsg/linux_eal_parameters>`
 or :doc:`EAL parameters (FreeBSD) <../freebsd_gsg/freebsd_eal_parameters>` for
@@ -53,7 +53,7 @@ a list of available EAL command-line options.
 
 
 Flow Performance Options
-
+
 
 The following are the command-line options for the flow performance 
application.
 They must be separated from the EAL options, shown in the previous section,
-- 
2.27.0



[dpdk-dev] [PATCH v5] usertools: add huge page setup script

2020-09-05 Thread Stephen Hemminger
This is an improved version of the setup of huge pages
bases on earlier DPDK setup. Differences are:
   * it autodetects NUMA vs non NUMA
   * it allows setting different page sizes
 recent kernels support multiple sizes.
   * it accepts a parameter in bytes (not pages).

If necessary the steps of clearing old settings and mounting/umounting
can be done individually.

Signed-off-by: Stephen Hemminger 
---
v5 -- cleanup help messages
  add documentation and install script

v4 -- more review feedback
  use argparser rather than getopt (thanks Bruce)
  silently handle already mounted type errors
  handle exceptions for permission and file not found
  fix numa bugs
  code now passes pylint

v3 -- incorporate review feedback
  add missing SPDX and env header
  overengineer the memory prefix string code
  add numa node argument
  fix some pylint warnings

 doc/guides/tools/hugepagesetup.rst |  79 +
 doc/guides/tools/index.rst |   1 +
 usertools/hugepage_setup.py| 271 +
 usertools/meson.build  |   7 +-
 4 files changed, 357 insertions(+), 1 deletion(-)
 create mode 100644 doc/guides/tools/hugepagesetup.rst
 create mode 100755 usertools/hugepage_setup.py

diff --git a/doc/guides/tools/hugepagesetup.rst 
b/doc/guides/tools/hugepagesetup.rst
new file mode 100644
index ..b1a5a8993a25
--- /dev/null
+++ b/doc/guides/tools/hugepagesetup.rst
@@ -0,0 +1,79 @@
+..  SPDX-License-Identifier: BSD-3-Clause
+Copyright (c) 2020 Microsoft Corporation
+
+hugepage_setup Application
+==
+
+The ``hugepage_setup`` tool is a Data Plane Development Kit (DPDK) utility
+that helps in reserving hugepages.
+As well as checking for current settings.
+
+
+Running the Application
+---
+
+The tool has a number of command line options:
+
+.. code-block:: console
+
+
+   hugepage_setup [options]
+   
+
+OPTIONS
+---
+
+* ``-h, --help``
+
+Display usage information and quit
+
+* ``-s, --show``
+
+Print the current huge page configuration
+
+* ``-c driver, --clear``
+
+Clear existing huge page reservation
+
+* ``-m, --mount``
+
+Mount the huge page filesystem
+
+* ``-u, --unmount``
+
+Unmount the huge page filesystem
+
+* ``-n NODE, --node=NODE``
+
+   Set NUMA node to reserve pages on
+
+* ``-p SIZE, --pagesize=SIZE``
+
+   Select hugepage size to use.
+   If not specified the default system huge page size is used.
+
+* ``-r SIZE, --reserve=SIZE``
+
+   Reserve huge pages.
+   Size is in bytes with K, M or G suffix.
+
+* ``--setup SIZE``
+
+   Short cut to clear, unmount, reserve and mount.
+
+.. warning::
+
+While any user can run the ``hugepage_setup`` script to view the
+status of huge pages, modifying the setup requires root privileges.
+
+
+Examples
+
+
+To display current huge page settings::
+
+   hugepage_setup -s
+
+To a complete setup of with 2 Gigabyte of 1G huge pages::
+
+   hugepage_setup -p 1G --setup 2G
diff --git a/doc/guides/tools/index.rst b/doc/guides/tools/index.rst
index c721943606f9..25c953ab01d4 100644
--- a/doc/guides/tools/index.rst
+++ b/doc/guides/tools/index.rst
@@ -11,6 +11,7 @@ DPDK Tools User Guides
 proc_info
 pdump
 pmdinfo
+hugepagesetup
 devbind
 flow-perf
 testbbdev
diff --git a/usertools/hugepage_setup.py b/usertools/hugepage_setup.py
new file mode 100755
index ..bec010883e63
--- /dev/null
+++ b/usertools/hugepage_setup.py
@@ -0,0 +1,271 @@
+#! /usr/bin/env python3
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright (c) 2020 Microsoft Corporation
+"""Script to query and setup huge pages for DPDK applications."""
+
+import argparse
+import glob
+import os
+import re
+import sys
+from math import log2
+
+# Standard binary prefix
+BINARY_PREFIX = "KMG"
+
+# systemd mount point for huge pages
+HUGE_MOUNT = "/dev/hugepages"
+
+
+def fmt_memsize(sz_k):
+'''Format memory size in kB into conventional format'''
+if sz_k.isdigit():
+return int(sz_k) / 1024
+logk = int(log2(sz_k) / 10)
+return '{}{}b'.format(int(sz_k / (2**(logk * 10))), BINARY_PREFIX[logk])
+
+
+def get_memsize(arg):
+'''Convert memory size with suffix to kB'''
+match = re.match(r'(\d+)([' + BINARY_PREFIX + r']?)$', arg.upper())
+if match is None:
+sys.exit('{} is not a valid page size'.format(arg))
+num = float(match.group(1))
+suffix = match.group(2)
+if suffix == "":
+return int(num / 1024)
+idx = BINARY_PREFIX.find(suffix)
+return int(num * (2**(idx * 10)))
+
+
+def is_numa():
+'''Test if NUMA is necessary on this system'''
+return os.path.exists('/sys/devices/system/node')
+
+
+def get_hugepages(path):
+'''Read number of reserved pages'''
+with open(path + '/nr_hugepages') as nr_hugpages:
+return int(nr_hugpages.read())
+return 0
+
+
+def set_hugepag