From: Stephen Hemminger <stephen@networkplumber.org>
To: "Jasper Tran O'Leary" <jtranoleary@google.com>
Cc: dev@dpdk.org
Subject: Re: [PATCH 0/9] net/gve: support proactive device reset
Date: Tue, 27 Oct 2026 13:50:12 -0700 [thread overview]
Message-ID: <20261027135012.25235518@phoenix.local> (raw)
In-Reply-To: <20261027185420.724684-1-jtranoleary@google.com>
On Tue, 27 Oct 2026 18:54:09 +0000
"Jasper Tran O'Leary" <jtranoleary@google.com> wrote:
> This series adds support for proactive device reset
> (RTE_ETH_ERROR_HANDLE_MODE_PROACTIVE) to the GVE driver, replacing the
> existing passive reset implementation. When the device requests a reset,
> the driver now automatically recovers the control plane and recreates RX
> and TX queues without requiring the application to manually reconfigure
> the port.
>
> To support automatic recovery safely while traffic is running, this
> series:
> - Fixes a pre-existing leak of the flow subsystem on device init
> failure.
> - Saves RX and TX queue setup parameters and versions queue memzone
> names by reset generation so queues can be recreated before old queue
> memory is freed.
> - Defers freeing retired queue memory ("zombie" queues) until after a
> grace period so concurrent datapath threads can safely drain after
> packet burst functions are redirected to dummy handlers.
> - Splits device resource setup and teardown into host memory allocation
> and hardware configuration so host DMA memory can be kept across
> resets and re-registered with the device.
> - Adds a reset mutex and moves device status polling off the shared DPDK
> alarm/interrupt thread onto a dedicated control thread.
> - Implements proactive recovery and emits the standard DPDK recovery
> lifecycle events (RTE_ETH_EVENT_ERR_RECOVERING,
> RTE_ETH_EVENT_RECOVERY_SUCCESS, and RTE_ETH_EVENT_RECOVERY_FAILED).
>
> Jasper Tran O'Leary (8):
> net/gve: free flow subsystem on dev init failure
> net/gve: snapshot queue configurations
> net/gve: add deferred queue memory reclamation
> net/gve: separate device resource alloc and config
> net/gve: add dedicated mutex for device reset
> net/gve: add check for device reset to AQ ctrl ops
> net/gve: implement proactive device reset
> net/gve: remove unused device reset parameter
>
> Joshua Washington (1):
> net/gve: move dev status poller to its own thread
>
> doc/guides/nics/gve.rst | 67 +-
> doc/guides/rel_notes/release_26_11.rst | 5 +
> drivers/net/gve/base/gve.h | 1 +
> drivers/net/gve/gve_ethdev.c | 775 ++++++++++++++------
> drivers/net/gve/gve_ethdev.h | 87 ++-
> drivers/net/gve/gve_rx.c | 36 +-
> drivers/net/gve/gve_rx_dqo.c | 36 +-
> drivers/net/gve/gve_tx.c | 32 +-
> drivers/net/gve/gve_tx_dqo.c | 35 +-
> 9 files changed, 813 insertions(+), 261 deletions(-)
>
Lots of issues in AI review
Subject: Re: [PATCH 0/9] net/gve: proactive device reset
Series applied to main except 7/9, which needs a rebase: the
gve_ethdev.c include context (<rte_cycles.h>) and the reflowed
Device Reset text in gve.rst do not match current main. With the
context fixed up, every commit builds with -Dwerror=true.
The overall approach (snapshot queue config, zombie queues,
generation-suffixed memzones, dedicated poller thread) is reasonable.
The main problems are with the ethdev contracts for rte_eth_dev_reset()
and RTE_ETH_EVENT_RECOVERY_SUCCESS, and with datapath ordering on
weakly ordered CPUs (Axion/Arm instances are a real target for gve).
Errors
------
[PATCH 7/9] net/gve: implement proactive device reset
1. gve_internal_recover_device() calls gve_dev_start() unconditionally.
- rte_eth_dev_reset() stops the port before calling dev_reset, and
its documented contract is that the port comes back stopped and
the application then calls configure/queue_setup/start. With
this patch the port comes back started, so the application's
rte_eth_dev_configure() fails with -EBUSY.
- After 9/9 the poller runs from probe until close, so a
device-requested reset on a stopped or never-configured port
sets dev_started = 1 behind the application's back.
- gve.rst says "Restarts the device (if it was previously
started)", which the code does not do.
Record the state on entry and only restart if it was started:
bool was_started = dev->data->dev_started;
...
if (was_started) {
ret = gve_dev_start(dev);
...
}
2. Configuration that RTE_ETH_EVENT_RECOVERY_SUCCESS promises to
retain is lost. Per rte_ethdev.h, MTU and RSS configuration set
via rte_eth_dev_rss_* must survive recovery. The recovery path
frees priv->rss_config and never re-issues set_mtu or
configure_rss, so the device silently reverts to its defaults.
Replay dev->data->mtu and the saved RSS key/hash types/RETA
after gve_configure_device_resources().
3. Flow rule state is left stale. The device loses its rules on
reset and gve does not advertise RTE_ETH_DEV_CAPA_FLOW_RULE_KEEP,
but priv->active_flows and the rule-ID bitmap are kept. A later
rte_flow_destroy() sends a destroy for a rule the device no longer
has, and rule IDs stay marked in use. Either re-program the rules
during recovery and set FLOW_RULE_KEEP, or tear down and re-init
the flow subsystem as the old dev_reset path did.
4. Datapath ordering. The writer does:
fp_ops.rx_pkt_burst = dummy;
fence(release);
dev->data->rx_queues[i] = NULL;
rte_eth_rx_burst() loads rxq.data[queue_id] and rx_pkt_burst with
no ordering between them. On Arm a reader can observe the NULL
queue pointer together with the old gve_recv_pkts, and dereference
NULL. A release fence on the writer side alone does not help.
Do not store NULL into the live queue array during recovery. Build
the new queue first, then publish it with a single store and hand
the old one to the zombie list. Any reader then sees either the old
(still mapped) queue or the new one. That needs an internal setup
variant that does not call gve_rx_queue_release() on the existing
slot.
5. Failed recovery leaves the port in a state that crashes later.
recover_fail frees the admin queue and NULLs all queues but leaves
dev_started set. A subsequent rte_eth_dev_stop() goes to
gve_stop_tx_queues(), which issues destroy_tx_queues over the freed
admin queue, then gve_tx_queue_stop() which passes a NULL txq to
gve_release_txq_mbufs(). Clear dev_started on failure and make
stop/close tolerate !gve_get_admin_queue_ok() and NULL queues.
[PATCH 9/9] net/gve: move dev status poller to its own thread
6. Lost update on state_flags. rte_bit_relaxed_set32/clear32 are
plain read-modify-write on a shared word. The poller thread
updates DEVICE_RESOURCES_OK, ADMIN_QUEUE_OK and DEVICE_RINGS_OK
during recovery while gve_dev_close() clears STATUS_POLLER_OK from
the application thread. If they overlap, the poller can write back
a stale word with STATUS_POLLER_OK still set; the loop never exits
and rte_thread_join() in close hangs. The fences around the relaxed
bit ops do not make the RMW atomic.
Use a separate flag:
RTE_ATOMIC(bool) dev_status_poller_run;
rte_atomic_store_explicit(&priv->dev_status_poller_run, false,
rte_memory_order_release);
...
while (rte_atomic_load_explicit(&priv->dev_status_poller_run,
rte_memory_order_acquire))
Warnings
--------
[PATCH 2/9] net/gve: snapshot queue configurations
7. Memzone names grow without bound. rte_eth_dma_zone_reserve()
builds "eth_p%d_q%d_%s" in a 32-byte buffer. With
"rx_compl_ring_g%u", a 3-digit port and queue already reach the
limit at reset_generation >= 100, after which setup fails with
ENAMETOOLONG and recovery fails. Since gve_add_zombie_*_queue()
frees any older zombie for the same queue id, only two generations
are ever live; use (reset_generation & 1) and shorter names
("rxc_g%u").
8. rxq_configs/txq_configs (and zombie_rx/tx_queues in 3/9) are
CPU-only bookkeeping used by the primary. Use calloc()/free()
instead of rte_zmalloc().
[PATCH 3/9] net/gve: add deferred queue memory reclamation
9. zombie_lock and zombie_next are never used. Drop them.
[PATCH 5/9] net/gve: add dedicated mutex for device reset
10. PTHREAD_MUTEX_RECURSIVE is set on the shared mutexattr, so
flow_rule_lock and nic_ts_lock silently become recursive too.
Recursion is only needed because recovery calls gve_dev_start()
with reset_lock held. Split out an unlocked helper and keep the
mutex non-recursive:
static int gve_dev_start_locked(struct rte_eth_dev *dev);
static int
gve_dev_start(struct rte_eth_dev *dev)
{
...
pthread_mutex_lock(&priv->reset_lock);
ret = gve_dev_start_locked(dev);
pthread_mutex_unlock(&priv->reset_lock);
return ret;
}
[PATCH 7/9] net/gve: implement proactive device reset
11. The driver no longer raises RTE_ETH_EVENT_INTR_RESET. Existing
applications that registered for it will stop receiving it. Say
so in the release note entry, not just in gve.rst.
12. Commit message says recovery runs in a "dedicated control
recovery thread"; in this patch it runs from the EAL alarm
callback. The thread only appears in 9/9. Also "supercedes" ->
"supersedes".
[PATCH 9/9] net/gve: move dev status poller to its own thread
13. gve_dev_reset() calls gve_stop_dev_status_polling() without
checking gve_get_dev_status_poller_ok(). If thread creation
failed at probe, rte_thread_join() is called on an uninitialized
rte_thread_t. Check the flag as gve_dev_close() does.
prev parent reply other threads:[~2026-10-27 20:50 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-27 18:54 [PATCH 0/9] net/gve: support proactive device reset Jasper Tran O'Leary
2026-10-27 18:54 ` [PATCH 1/9] net/gve: free flow subsystem on dev init failure Jasper Tran O'Leary
2026-10-27 18:54 ` [PATCH 2/9] net/gve: snapshot queue configurations Jasper Tran O'Leary
2026-10-27 18:54 ` [PATCH 3/9] net/gve: add deferred queue memory reclamation Jasper Tran O'Leary
2026-10-27 18:54 ` [PATCH 4/9] net/gve: separate device resource alloc and config Jasper Tran O'Leary
2026-10-27 18:54 ` [PATCH 5/9] net/gve: add dedicated mutex for device reset Jasper Tran O'Leary
2026-10-27 18:54 ` [PATCH 6/9] net/gve: add check for device reset to AQ ctrl ops Jasper Tran O'Leary
2026-10-27 18:54 ` [PATCH 7/9] net/gve: implement proactive device reset Jasper Tran O'Leary
2026-10-27 18:54 ` [PATCH 8/9] net/gve: remove unused device reset parameter Jasper Tran O'Leary
2026-10-27 18:54 ` [PATCH 9/9] net/gve: move dev status poller to its own thread Jasper Tran O'Leary
2026-10-27 20:50 ` Stephen Hemminger [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261027135012.25235518@phoenix.local \
--to=stephen@networkplumber.org \
--cc=dev@dpdk.org \
--cc=jtranoleary@google.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.