[dpdk-dev] [PATCH v4 4/5] net/hns3: add Rx buffer size to Rx qinfo query
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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