From patchwork Thu May 2 21:31:45 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stephen Hemminger X-Patchwork-Id: 139821 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id D037343F6C; Thu, 2 May 2024 23:37:31 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 677DF4069F; Thu, 2 May 2024 23:36:43 +0200 (CEST) Received: from mail-pg1-f169.google.com (mail-pg1-f169.google.com [209.85.215.169]) by mails.dpdk.org (Postfix) with ESMTP id 1196440647 for ; Thu, 2 May 2024 23:36:36 +0200 (CEST) Received: by mail-pg1-f169.google.com with SMTP id 41be03b00d2f7-5e42b4bbfa4so5207445a12.1 for ; Thu, 02 May 2024 14:36:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=networkplumber-org.20230601.gappssmtp.com; s=20230601; t=1714685795; x=1715290595; darn=dpdk.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=IbN2sX0BP0OYIDnVo5eo29NaVs4GWK+wgdCR6uTImtw=; b=kPrcCJ8sBHG1WBWy30bob/3KMf9sIszV1GDBFdex4uf8Ggaz7mZ1EI3Imh2d2qzNlM rLZPBBRcfKaoGJkSyNix4cnx8HzhYwy9UFotzbK8H/PJTquHSfJix+7SnaslJHnAtyiA N7vNu7ZVx0WJ+eshKTYAdZbhHSiqz2E+XswxOLKLIkyjSQDarjQ6tV5KpJy3A62oudFN DFfoi0HovsaAlW74+x+jrSUhMHmfyDl+mXFldVH4hNMsBbxS1b/eLbjQHcdHkqm4nLFP Hh9EI0t0FPq24DXogO/RyoHeXUeEeanVrFoT0eTLukzTtLOn8NfQoE5eDwReD7jYRFs8 ZJ3A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1714685795; x=1715290595; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=IbN2sX0BP0OYIDnVo5eo29NaVs4GWK+wgdCR6uTImtw=; b=qjb1TAKrOipmyyOMOkYsJAlI18YmlaL5jPJ5OOZPltPN+tZj2cAKp/1bzOYEzzOnb/ JTeKPC4ch9S8z9Z7a19SygccfRVAP0jmDdh0weOEuFrVT39EJYh83Y2XKau+Z2PL4vrT d4aGO8eagbg1BwRaRGS88NyMzV+Dv2W9YexRky/GaW+qcSS0V3d7s2FoJ1l3KVV7sW5I 502e8+tJQ5mJq/oc2+OZz6oyZLhafmc0ls1SyjYvYFmJS/u16gaLpbeMaCka4PAccsIh +aWoOSAol0EyvpBIM+BZqDcsZVAtGAtZQutA2qlnnFYdqK+fdNozX5p2BDJ/EWZiWNCF 91fQ== X-Gm-Message-State: AOJu0Yz3uFgfC4eRvZrmnCYqXv0r0D8BdP0CHOhonpFKTvO1y6oOanIu B61av+1lDGhwTAdH4XRGJ7At4zLYm9ZcO8TqCcEWDyIe2z3jDott80cDLz8C+6OQppaQerihdp2 40VC+eg== X-Google-Smtp-Source: AGHT+IFzF2wEZ8ZhWY9E/eYWTCDMHdBpJIfWzxsT7KfSXlGopHSCLPtqyo6vyCC9zRjxyEaprv/d7A== X-Received: by 2002:a05:6a20:d493:b0:1a7:aecd:997c with SMTP id im19-20020a056a20d49300b001a7aecd997cmr1188278pzb.0.1714685795156; Thu, 02 May 2024 14:36:35 -0700 (PDT) Received: from hermes.local (204-195-96-226.wavecable.com. [204.195.96.226]) by smtp.gmail.com with ESMTPSA id f14-20020a056a001ace00b006f3eee787d5sm1804829pfv.18.2024.05.02.14.36.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 02 May 2024 14:36:34 -0700 (PDT) From: Stephen Hemminger To: dev@dpdk.org Cc: Stephen Hemminger Subject: [PATCH v12 09/12] net/tap: simplify internals Date: Thu, 2 May 2024 14:31:45 -0700 Message-ID: <20240502213618.11391-10-stephen@networkplumber.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240502213618.11391-1-stephen@networkplumber.org> References: <20240130034925.44869-1-stephen@networkplumber.org> <20240502213618.11391-1-stephen@networkplumber.org> MIME-Version: 1.0 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org The names of Linux network devices are IFNAMSIZ(16) not the same as DPDK which has up to 64 characters. Don't need to hold onto the whole ifreq to save the remote interface flags. Make sure packet and byte counters are read once, so that global and per-queue values add up. No need for separate rx_nombuf counter since there is an alloc_failed value in ethdev. Keep only the statistics that are used. I.e no ipackets on tx queues etc. Signed-off-by: Stephen Hemminger --- drivers/net/tap/rte_eth_tap.c | 138 ++++++++++++++++++---------------- drivers/net/tap/rte_eth_tap.h | 22 +++--- 2 files changed, 83 insertions(+), 77 deletions(-) diff --git a/drivers/net/tap/rte_eth_tap.c b/drivers/net/tap/rte_eth_tap.c index d847565073..3614aaf1dc 100644 --- a/drivers/net/tap/rte_eth_tap.c +++ b/drivers/net/tap/rte_eth_tap.c @@ -46,6 +46,11 @@ #include #include +/* Used to snapshot statistics */ +#ifndef READ_ONCE +#define READ_ONCE(var) (*((volatile typeof(var) *)(&(var)))) +#endif + /* Linux based path to the TUN device */ #define TUN_TAP_DEV_PATH "/dev/net/tun" #define DEFAULT_TAP_NAME "dtap" @@ -212,7 +217,7 @@ tun_alloc(struct pmd_internals *pmd, int is_keepalive, int persistent) * and need to find the resulting device. */ TAP_LOG(DEBUG, "Device name is '%s'", ifr.ifr_name); - strlcpy(pmd->name, ifr.ifr_name, RTE_ETH_NAME_MAX_LEN); + strlcpy(pmd->name, ifr.ifr_name, IFNAMSIZ); if (is_keepalive) { /* @@ -454,7 +459,7 @@ pmd_rx_burst(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) /* Packet couldn't fit in the provided mbuf */ if (unlikely(rxq->pi.flags & TUN_PKT_STRIP)) { - rxq->stats.ierrors++; + rxq->stats.errors++; continue; } @@ -466,7 +471,8 @@ pmd_rx_burst(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) struct rte_mbuf *buf = rte_pktmbuf_alloc(rxq->mp); if (unlikely(!buf)) { - rxq->stats.rx_nombuf++; + rte_eth_devices[rxq->in_port].data->rx_mbuf_alloc_failed++; + /* No new buf has been allocated: do nothing */ if (!new_tail || !seg) goto end; @@ -511,8 +517,8 @@ pmd_rx_burst(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) num_rx_bytes += mbuf->pkt_len; } end: - rxq->stats.ipackets += num_rx; - rxq->stats.ibytes += num_rx_bytes; + rxq->stats.packets += num_rx; + rxq->stats.bytes += num_rx_bytes; if (trigger && num_rx < nb_pkts) rxq->trigger_seen = trigger; @@ -692,7 +698,7 @@ pmd_tx_burst(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) tso_segsz = mbuf_in->tso_segsz + hdrs_len; if (unlikely(tso_segsz == hdrs_len) || tso_segsz > *txq->mtu) { - txq->stats.errs++; + txq->stats.errors++; break; } gso_ctx->gso_size = tso_segsz; @@ -730,7 +736,7 @@ pmd_tx_burst(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) ret = tap_write_mbufs(txq, num_mbufs, mbuf, &num_packets, &num_tx_bytes); if (ret == -1) { - txq->stats.errs++; + txq->stats.errors++; /* free tso mbufs */ if (num_tso_mbufs > 0) rte_pktmbuf_free_bulk(mbuf, num_tso_mbufs); @@ -748,9 +754,8 @@ pmd_tx_burst(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) } } - txq->stats.opackets += num_packets; - txq->stats.errs += nb_pkts - num_tx; - txq->stats.obytes += num_tx_bytes; + txq->stats.packets += num_packets; + txq->stats.bytes += num_tx_bytes; return num_tx; } @@ -1047,43 +1052,44 @@ tap_dev_info(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info) static int tap_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *tap_stats) { - unsigned int i, imax; - unsigned long rx_total = 0, tx_total = 0, tx_err_total = 0; - unsigned long rx_bytes_total = 0, tx_bytes_total = 0; - unsigned long rx_nombuf = 0, ierrors = 0; + unsigned int i; const struct pmd_internals *pmd = dev->data->dev_private; + uint64_t bytes, packets; /* rx queue statistics */ - imax = (dev->data->nb_rx_queues < RTE_ETHDEV_QUEUE_STAT_CNTRS) ? - dev->data->nb_rx_queues : RTE_ETHDEV_QUEUE_STAT_CNTRS; - for (i = 0; i < imax; i++) { - tap_stats->q_ipackets[i] = pmd->rxq[i].stats.ipackets; - tap_stats->q_ibytes[i] = pmd->rxq[i].stats.ibytes; - rx_total += tap_stats->q_ipackets[i]; - rx_bytes_total += tap_stats->q_ibytes[i]; - rx_nombuf += pmd->rxq[i].stats.rx_nombuf; - ierrors += pmd->rxq[i].stats.ierrors; + for (i = 0; i < dev->data->nb_rx_queues; i++) { + const struct rx_queue *rxq = &pmd->rxq[i]; + + packets = READ_ONCE(rxq->stats.packets); + bytes = READ_ONCE(rxq->stats.bytes); + + tap_stats->ipackets += packets; + tap_stats->ibytes += bytes; + tap_stats->ierrors += rxq->stats.errors; + + if (i < RTE_ETHDEV_QUEUE_STAT_CNTRS) { + tap_stats->q_ipackets[i] = packets; + tap_stats->q_ibytes[i] = bytes; + } } /* tx queue statistics */ - imax = (dev->data->nb_tx_queues < RTE_ETHDEV_QUEUE_STAT_CNTRS) ? - dev->data->nb_tx_queues : RTE_ETHDEV_QUEUE_STAT_CNTRS; - - for (i = 0; i < imax; i++) { - tap_stats->q_opackets[i] = pmd->txq[i].stats.opackets; - tap_stats->q_obytes[i] = pmd->txq[i].stats.obytes; - tx_total += tap_stats->q_opackets[i]; - tx_err_total += pmd->txq[i].stats.errs; - tx_bytes_total += tap_stats->q_obytes[i]; - } - - tap_stats->ipackets = rx_total; - tap_stats->ibytes = rx_bytes_total; - tap_stats->ierrors = ierrors; - tap_stats->rx_nombuf = rx_nombuf; - tap_stats->opackets = tx_total; - tap_stats->oerrors = tx_err_total; - tap_stats->obytes = tx_bytes_total; + for (i = 0; i < dev->data->nb_tx_queues; i++) { + const struct tx_queue *txq = &pmd->txq[i]; + + packets = READ_ONCE(txq->stats.packets); + bytes = READ_ONCE(txq->stats.bytes); + + tap_stats->opackets += packets; + tap_stats->obytes += bytes; + tap_stats->oerrors += txq->stats.errors; + + if (i < RTE_ETHDEV_QUEUE_STAT_CNTRS) { + tap_stats->q_opackets[i] = packets; + tap_stats->q_obytes[i] = bytes; + } + } + return 0; } @@ -1094,14 +1100,8 @@ tap_stats_reset(struct rte_eth_dev *dev) struct pmd_internals *pmd = dev->data->dev_private; for (i = 0; i < RTE_PMD_TAP_MAX_QUEUES; i++) { - pmd->rxq[i].stats.ipackets = 0; - pmd->rxq[i].stats.ibytes = 0; - pmd->rxq[i].stats.ierrors = 0; - pmd->rxq[i].stats.rx_nombuf = 0; - - pmd->txq[i].stats.opackets = 0; - pmd->txq[i].stats.errs = 0; - pmd->txq[i].stats.obytes = 0; + memset(&pmd->rxq[i].stats, 0, sizeof(struct pkt_stats)); + memset(&pmd->txq[i].stats, 0, sizeof(struct pkt_stats)); } return 0; @@ -1156,9 +1156,13 @@ tap_dev_close(struct rte_eth_dev *dev) } if (internals->remote_if_index) { + struct ifreq remote_ifr; + + strlcpy(remote_ifr.ifr_name, internals->remote_iface, IFNAMSIZ); + remote_ifr.ifr_flags = internals->remote_flags; + /* Restore initial remote state */ - int ret = ioctl(internals->ioctl_sock, SIOCSIFFLAGS, - &internals->remote_initial_flags); + int ret = ioctl(internals->ioctl_sock, SIOCSIFFLAGS, &remote_ifr); if (ret) TAP_LOG(ERR, "restore remote state failed: %d", ret); @@ -2067,16 +2071,22 @@ eth_dev_tap_create(struct rte_vdev_device *vdev, const char *tap_name, LIST_INIT(&pmd->flows); if (strlen(remote_iface)) { + struct ifreq remote_ifr; + pmd->remote_if_index = if_nametoindex(remote_iface); if (!pmd->remote_if_index) { TAP_LOG(ERR, "%s: failed to get %s if_index.", pmd->name, remote_iface); goto error_remote; } - strlcpy(pmd->remote_iface, remote_iface, RTE_ETH_NAME_MAX_LEN); + strlcpy(pmd->remote_iface, remote_iface, IFNAMSIZ); + + memset(&remote_ifr, 0, sizeof(ifr)); + strlcpy(remote_ifr.ifr_name, remote_iface, IFNAMSIZ); /* Save state of remote device */ - tap_ioctl(pmd, SIOCGIFFLAGS, &pmd->remote_initial_flags, 0, REMOTE_ONLY); + tap_ioctl(pmd, SIOCGIFFLAGS, &remote_ifr, 0, REMOTE_ONLY); + pmd->remote_flags = remote_ifr.ifr_flags; /* Replicate remote MAC address */ if (tap_ioctl(pmd, SIOCGIFHWADDR, &ifr, 0, REMOTE_ONLY) < 0) { @@ -2190,10 +2200,10 @@ set_interface_name(const char *key __rte_unused, value); return -1; } - strlcpy(name, value, RTE_ETH_NAME_MAX_LEN); + strlcpy(name, value, IFNAMSIZ); } else { /* use tap%d which causes kernel to choose next available */ - strlcpy(name, DEFAULT_TAP_NAME "%d", RTE_ETH_NAME_MAX_LEN); + strlcpy(name, DEFAULT_TAP_NAME "%d", IFNAMSIZ); } return 0; } @@ -2211,7 +2221,7 @@ set_remote_iface(const char *key __rte_unused, value); return -1; } - strlcpy(name, value, RTE_ETH_NAME_MAX_LEN); + strlcpy(name, value, IFNAMSIZ); } return 0; @@ -2262,13 +2272,13 @@ rte_pmd_tun_probe(struct rte_vdev_device *dev) const char *name, *params; int ret; struct rte_kvargs *kvlist = NULL; - char tun_name[RTE_ETH_NAME_MAX_LEN]; - char remote_iface[RTE_ETH_NAME_MAX_LEN]; + char tun_name[IFNAMSIZ]; + char remote_iface[IFNAMSIZ]; struct rte_eth_dev *eth_dev; name = rte_vdev_device_name(dev); params = rte_vdev_device_args(dev); - memset(remote_iface, 0, RTE_ETH_NAME_MAX_LEN); + memset(remote_iface, 0, IFNAMSIZ); if (rte_eal_process_type() == RTE_PROC_SECONDARY && strlen(params) == 0) { @@ -2284,7 +2294,7 @@ rte_pmd_tun_probe(struct rte_vdev_device *dev) } /* use tun%d which causes kernel to choose next available */ - strlcpy(tun_name, DEFAULT_TUN_NAME "%d", RTE_ETH_NAME_MAX_LEN); + strlcpy(tun_name, DEFAULT_TUN_NAME "%d", IFNAMSIZ); if (params && (params[0] != '\0')) { TAP_LOG(DEBUG, "parameters (%s)", params); @@ -2424,8 +2434,8 @@ rte_pmd_tap_probe(struct rte_vdev_device *dev) int ret; struct rte_kvargs *kvlist = NULL; int speed; - char tap_name[RTE_ETH_NAME_MAX_LEN]; - char remote_iface[RTE_ETH_NAME_MAX_LEN]; + char tap_name[IFNAMSIZ]; + char remote_iface[IFNAMSIZ]; struct rte_ether_addr user_mac = { .addr_bytes = {0} }; struct rte_eth_dev *eth_dev; int tap_devices_count_increased = 0; @@ -2479,8 +2489,8 @@ rte_pmd_tap_probe(struct rte_vdev_device *dev) speed = RTE_ETH_SPEED_NUM_10G; /* use tap%d which causes kernel to choose next available */ - strlcpy(tap_name, DEFAULT_TAP_NAME "%d", RTE_ETH_NAME_MAX_LEN); - memset(remote_iface, 0, RTE_ETH_NAME_MAX_LEN); + strlcpy(tap_name, DEFAULT_TAP_NAME "%d", IFNAMSIZ); + memset(remote_iface, 0, IFNAMSIZ); if (params && (params[0] != '\0')) { TAP_LOG(DEBUG, "parameters (%s)", params); diff --git a/drivers/net/tap/rte_eth_tap.h b/drivers/net/tap/rte_eth_tap.h index ce4322ad04..8f9ab613c7 100644 --- a/drivers/net/tap/rte_eth_tap.h +++ b/drivers/net/tap/rte_eth_tap.h @@ -34,13 +34,9 @@ enum rte_tuntap_type { }; struct pkt_stats { - uint64_t opackets; /* Number of output packets */ - uint64_t ipackets; /* Number of input packets */ - uint64_t obytes; /* Number of bytes on output */ - uint64_t ibytes; /* Number of bytes on input */ - uint64_t errs; /* Number of TX error packets */ - uint64_t ierrors; /* Number of RX error packets */ - uint64_t rx_nombuf; /* Nb of RX mbuf alloc failures */ + uint64_t packets; /* Number of packets */ + uint64_t bytes; /* Number of bytes */ + uint64_t errors; /* Number of errors */ }; struct rx_queue { @@ -68,15 +64,16 @@ struct tx_queue { struct pmd_internals { struct rte_eth_dev *dev; /* Ethernet device. */ - char remote_iface[RTE_ETH_NAME_MAX_LEN]; /* Remote netdevice name */ - char name[RTE_ETH_NAME_MAX_LEN]; /* Internal Tap device name */ + char remote_iface[IFNAMSIZ]; /* Remote netdevice name */ + char name[IFNAMSIZ]; /* Internal Tap device name */ int type; /* Type field - TUN|TAP */ int persist; /* 1 if keep link up, else 0 */ struct rte_ether_addr eth_addr; /* Mac address of the device port */ - struct ifreq remote_initial_flags;/* Remote netdevice flags on init */ + uint16_t remote_flags; /* Remote netdevice flags on init */ int remote_if_index; /* remote netdevice IF_INDEX */ int if_index; /* IF_INDEX for the port */ int ioctl_sock; /* socket for ioctl calls */ + int ka_fd; /* keep-alive file descriptor */ #ifdef HAVE_TCA_FLOWER int nlsk_fd; /* Netlink socket fd */ @@ -88,12 +85,11 @@ struct pmd_internals { /* implicit rte_flow rules set when a remote device is active */ LIST_HEAD(tap_implicit_flows, rte_flow) implicit_flows; #endif + struct rte_intr_handle *intr_handle; /* LSC interrupt handle. */ + struct rte_mempool *gso_ctx_mp; /* Mempool for GSO packets */ struct rx_queue rxq[RTE_PMD_TAP_MAX_QUEUES]; /* List of RX queues */ struct tx_queue txq[RTE_PMD_TAP_MAX_QUEUES]; /* List of TX queues */ - struct rte_intr_handle *intr_handle; /* LSC interrupt handle. */ - int ka_fd; /* keep-alive file descriptor */ - struct rte_mempool *gso_ctx_mp; /* Mempool for GSO packets */ }; struct pmd_process_private {