net: mana: concurrent HWC requests and dynamic queue depth
Subsystems (5)
v6 cover net: mana: concurrent HWC requests and dynamic queue depth
This series picks up Long Li's v5 MANA Hardware Channel (HWC) work, addresses its review findings, and retains its four-patch feature lineage. Safety changes required by concurrency and repeated HWC reinitialization are folded into the patch which owns each behavior rather than posted as a separate fixes series.
I have taken over follow-up upstreaming from Long. Long remains the author of every patch, his existing sign-off is preserved, and I added mine for the changes and submission custody.
Patch 1 prepares HWC ownership for safe reinitialization. It serializes complete shared-memory transactions, tracks possible PF ownership, retains mappings after an unacknowledged destroy, fences the HWC EQ before releasing CQ state, and safely publishes and withdraws the HWC CQ table.
Patch 2 gives each slot independent completion state, withdraws caller storage before sender return, handles the response-versus-timeout race, and prevents depth-one slot reuse after a genuine timeout.
Patch 3 adds concurrent requests with bounded admission, serialized SQ posting, separate sender/response ownership, stale-response quarantine, coherent timeout updates, private setup publication, and sender draining.
Patch 4 rebuilds the depth-one bootstrap queues at validated depths from 2 through 128. It validates both reports, message limits and doorbells, keeps the untouched bootstrap channel for depth one or reports above 128, and restores fresh bootstrap queues after a failed rebuild only when teardown was acknowledged.
Generic Ethernet/RDMA CQ callback refcounting and generic service-work versus device-lifecycle serialization are independent pre-existing work and are intentionally excluded. Malformed-RX handling, duplicate-success correlation, and broad device-controlled allocation/timeout policy caps also remain separate follow-ups.
Changes in v6 (v5 -> v6):
- Keep the four-patch v5 structure while folding review-required HWC ownership, teardown, timeout, publication and fallback safety into their owning feature patches.
- Serialize complete ESTABLISH_HWC and DESTROY_HWC shared-memory transactions. Record possible PF ownership before MMIO submission and clear it only after DESTROY_HWC is acknowledged.
- Retain PF-visible queues after an indeterminate destroy. Fence the dedicated HWC EQ and withdraw its CQ from dispatch without freeing the mappings, then retry teardown before assigning fresh queues.
- Destroy the HWC EQ before CQ and completion state. Release-publish the CQ table and wait for IRQ-side RCU readers before freeing it, without adding per-completion refcount operations.
- Withdraw the caller's response buffer before return and quarantine a timed-out slot until its late response arrives or teardown cancels it.
- Return -EBUSY for healthy slot pressure and reserve -ETIMEDOUT for an admitted request which receives no response.
- Publish slots under the inflight lock, protect response state with the per-slot lock, and retain sender/response references until both sides finish.
- Synchronize hwc_timeout updates and publish the HWC only after queues, admission state, caller contexts and the direct EQ test are ready.
- Replace the goto-heavy request and channel-creation flows called out in review with focused admission, submission, wait, build, validation, rebuild and fallback helpers.
- Treat reported depth as a maximum: rebuild exactly for 2 through 128, retain untouched bootstrap queues for 1 or above 128, and require the rebuilt report to repeat the selected depth.
- Enforce directional request/response maxima against both the report and allocated buffers. Rebuild only for exact 4096-byte reports while permitting bootstrap operation for other nonzero maxima.
- Validate BAR page geometry and every stored doorbell. Invalidate the old HWC doorbell before re-establishment and suppress MMIO while the invalid sentinel is present, without adding full validation to each data-path doorbell ring.
- Remove the proposed capability bit because driver-version advertisement occurs after HWC establishment and cannot negotiate creation-time behavior.
- Preserve current net-next behavior which always uses the hardware-reported dest_vrq_id and dest_vrcq_id.
Changes in v5 (v4 -> v5):
- Shortened comments and documented the existing error paths in patches 1 and 2.
- Rejected apparent success from a response accepted before request submission.
- Guarded CQ unpublication when establishment failed before cq_table allocation.
- Required successful retry teardown before creating fresh bootstrap queues after an initial destroy failure.
Changes in v4 (return to net-next after the v3 split):
- Reworked the feature series into four standalone patches for handover, per-slot completion state, concurrency and dynamic depth.
- Added bounded admission, guarded sender accounting, timeout quarantine, queue-depth bounds, message-buffer sizing and rebuild validation.
- Reset routing IDs for each establish and rejected a missing doorbell.
Changes in v3 (v2 -> net v3, historical fixes-only posting):
- Split the combined series after maintainer feedback, posting fixes to net and deferring concurrency and dynamic depth.
- Added response-buffer withdrawal and stale-response handling.
- Removed pcie_flr() teardown fallback and retained resources after an unacknowledged destroy.
Changes in v2 (v1 -> v2):
- Bounds-checked the SGE pointer derived from inline OOB size.
- Protected active-sender accounting and drained senders during teardown and failure exits.
- Rebased on net-next e354f7d60f14.
v1:
- Combined CQ-table lifetime, queue sizing, RX validation, teardown, concurrent-request and dynamic-depth work in seven patches.
Validation:
- All four patches pass diff-check and strict checkpatch.
- Every patch passes targeted GCC 13 and Clang 18 W=1 MANA Ethernet/RDMA builds on base c66d93e68728.
- Sparse and Smatch add no diagnostics over that current-base baseline.
- Release kernel 7.3.0-rc4-mana-hwc-v6-4p-g7065a269bba5 booted via one-time GRUB entries on two Azure MANA VMs.
- Each VM passed 32-worker control stress, queue resizing from 8 to 4 and back, MTU/link changes, three standalone PCI remove/rescan cycles, and two further cycles while control queries ran concurrently.
- MANA rebound, peer connectivity recovered, and both RDMA links returned ACTIVE after every cycle. No new MANA error, timeout, warning, UAF, refcount, RCU, lockdep, KASAN or KCSAN report appeared.
- Fresh safe-kernel and four-patch 16-stream TCP receive throughput was 24.338 and 24.337 Gbit/s respectively. Concurrent control stress measured 24.339 Gbit/s.
- Four-stream 64-byte UDP sustained the requested 399.986 Mbit/s on both kernels; loss was 0.812% on the fresh safe baseline and 0.041% on the four-patch kernel.
- RDMA devices and links remained active. ib_write_bw reproduced the environment baseline status 21 / syndrome 0x1c6.
- The request, timeout, rebuild, fallback, message-limit and shared- memory state machines are unchanged from the previously injected depth/message/doorbell/destroy/response fault tests. Fresh runtime additionally exercised the new HWC-specific CQ publication path.
- Both VMs were finally rebooted to the known-good 7.3.0-rc5-mana-vmtest-g72d3fcf802c4 kernel with the safe saved_entry, empty next_entry, active MANA/RDMA and a 24.347 Gbit/s smoke test.
v5:
https://lore.kernel.org/all/[email protected]/
v4:
https://lore.kernel.org/all/[email protected]/
v3:
https://lore.kernel.org/all/[email protected]/
v2:
https://lore.kernel.org/all/[email protected]/
v1:
https://lore.kernel.org/all/[email protected]/
Long Li (4):
net: mana: prepare HWC ownership for safe reinitialization
net: mana: give each HWC message slot its own completion state
net: mana: support concurrent HWC requests
net: mana: add dynamic HWC queue depth with reinit path
.../net/ethernet/microsoft/mana/gdma_main.c | 129 ++- .../net/ethernet/microsoft/mana/hw_channel.c | 928 +++++++++++++++--- .../net/ethernet/microsoft/mana/shm_channel.c | 58 +- include/net/mana/gdma.h | 14 + include/net/mana/hw_channel.h | 56 +- include/net/mana/shm_channel.h | 10 +- 6 files changed, 1000 insertions(+), 195 deletions(-)
base-commit: c66d93e68728cfb5f40b40d0f24129d7768faf43
Signature · 1 line
2.43.0
PATCH v6 1/4 net: mana: prepare HWC ownership for safe reinitialization
From: Long Li <[email protected]>
Dynamic HWC queue sizing tears down the bootstrap queues and establishes a second channel before publishing it. Prepare the existing HWC ownership and teardown paths so that sequence cannot free or reuse state still reachable by either the PF or an EQ handler.
The shared-memory aperture carries one request at a time. Serialize the complete ESTABLISH_HWC and DESTROY_HWC transactions, including possession polling and response validation. Record setup_active immediately before the MMIO submission and clear it only after DESTROY_HWC is acknowledged.
Treat an unacknowledged destroy as retained PF ownership. Fence the HWC EQ and withdraw its CQ from dispatch, but keep all queue memory and wrappers for a later teardown retry. A new channel creation retries that retained context before assigning fresh queues to the PF.
Snapshot the bootstrap CQ count and CQ ID after INIT_DONE. Publish the fixed bound with the allocated table so later init events cannot grow the bound past the allocation. The EQ handler acquires the table pointer but does not take a per-event CQ reference; HWC teardown instead fences the dedicated EQ and waits for the existing IRQ-side RCU readers before freeing the table.
On acknowledged teardown, destroy the HWC EQ before the CQ and completion buffer, then release the TX and RX queues. This ordering makes both the normal reinitialization path and every failure unwind safe.
--- .../net/ethernet/microsoft/mana/gdma_main.c | 25 ++- .../net/ethernet/microsoft/mana/hw_channel.c | 150 +++++++++++++++--- .../net/ethernet/microsoft/mana/shm_channel.c | 58 ++++++- include/net/mana/gdma.h | 3 + include/net/mana/hw_channel.h | 4 + include/net/mana/shm_channel.h | 10 +- 6 files changed, 217 insertions(+), 33 deletions(-)
drivers/net/ethernet/microsoft/mana/gdma_main.c +20 -5
@@ -911,6 +911,7 @@ static void mana_gd_process_eqe(struct gdma_queue *eq)union gdma_eqe_info eqe_info;enum gdma_eqe_type type;struct gdma_event event; +struct gdma_queue **cq_table;struct gdma_queue *cq;struct gdma_eqe *eqe;u32 cq_id;
@@ -922,11 +923,16 @@ static void mana_gd_process_eqe(struct gdma_queue *eq)switch (type) {case GDMA_EQE_COMPLETION : cq_id = eqe->details[0 ] &0xFFFFFF ; -if (WARN_ON_ONCE (cq_id >= gc->max_num_cqs)) +/* The IRQ handler's RCU read-side section protects the table +* until HWC teardown has fenced its EQ and waited for readers. +*/ + cq_table =smp_load_acquire (&gc->cq_table); +if (!cq_table || cq_id >=READ_ONCE (gc->max_num_cqs))break ; - cq = gc->cq_table[cq_id]; -if (WARN_ON_ONCE (!cq || cq->type !=GDMA_CQ || cq->id != cq_id)) + cq =READ_ONCE (cq_table[cq_id]); +if (!cq ||WARN_ON_ONCE (cq->type !=GDMA_CQ || + cq->id != cq_id))break ;if (cq->cq.callback)
@@ -1150,23 +1156,32 @@ int mana_gd_test_eq(struct gdma_context *gc, struct gdma_queue *eq)return err; } -static void mana_gd_destroy_eq (struct gdma_context *gc,bool flush_evenets, +static void mana_gd_destroy_eq (struct gdma_context *gc,bool flush_events,struct gdma_queue *queue) {int err; -if (flush_evenets) { +if (queue->eq.msix_index ==INVALID_PCI_MSIX_INDEX ) +return ; + +if (flush_events) { err =mana_gd_test_eq (gc, queue);if (err &&mana_need_log (gc, err))dev_warn (gc->dev,"Failed to flush EQ: %d\n" , err); }mana_gd_deregister_irq (queue); + queue->eq.msix_index =INVALID_PCI_MSIX_INDEX ;if (queue->eq.disable_needed)mana_gd_disable_queue (queue); } +void mana_gd_fence_eq (struct gdma_context *gc,struct gdma_queue *queue) +{ +mana_gd_destroy_eq (gc, false, queue); +} +static int mana_gd_create_eq (struct gdma_dev *gd,const struct gdma_queue_spec *spec,bool create_hwq,struct gdma_queue *queue)
drivers/net/ethernet/microsoft/mana/hw_channel.c +128 -22
230 lines not on this page · raw message
drivers/net/ethernet/microsoft/mana/shm_channel.c +54 -4
95 lines not on this page · raw message
include/net/mana/gdma.h +3 -0
@@ -520,6 +520,9 @@ int mana_gd_create_mana_wq_cq(struct gdma_dev *gd,void mana_gd_destroy_queue (struct gdma_context *gc,struct gdma_queue *queue); +/* Remove an EQ from interrupt dispatch without freeing its queue memory. */ +void mana_gd_fence_eq (struct gdma_context *gc,struct gdma_queue *queue); +int mana_gd_poll_cq (struct gdma_queue *cq,struct gdma_comp *comp,int num_cqe);void mana_gd_ring_cq (struct gdma_queue *cq,u8 arm_bit);
include/net/mana/hw_channel.h +4 -0
@@ -185,6 +185,8 @@ struct hw_channel_context {u16 hwc_init_q_depth_max;u32 hwc_init_max_req_msg_size;u32 hwc_init_max_resp_msg_size; +u32 hwc_init_max_num_cqs; +u32 hwc_init_cq_id;struct completion hwc_init_eqe_comp;
@@ -199,6 +201,8 @@ struct hw_channel_context {u32 dest_vrcq_id;u32 hwc_timeout; +/* The PF may own the HWC queues while this is true. */ +bool setup_active;struct hwc_caller_ctx *caller_ctx; };
include/net/mana/shm_channel.h +8 -2
@@ -4,6 +4,8 @@#ifndef _SHM_CHANNEL_H#define _SHM_CHANNEL_H +#include <linux/mutex.h> +#define SMC_APERTURE_BITS 256#define SMC_BASIC_UNIT (sizeof(u32))#define SMC_APERTURE_DWORDS (SMC_APERTURE_BITS / (SMC_BASIC_UNIT * 8))
@@ -13,6 +15,9 @@struct shm_channel {struct device *dev;void __iomem *base; +/* Protects base and complete aperture request/response transactions. */ +struct mutex transaction_lock; +bool transaction_lock_initialized; }; void mana_smc_init(struct shm_channel *sc, struct device *dev,
@@ -20,8 +25,9 @@ void mana_smc_init(struct shm_channel *sc, struct device *dev,int mana_smc_setup_hwc (struct shm_channel *sc,bool reset_vf,u64 eq_addr,u64 cq_addr,u64 rq_addr,u64 sq_addr, -u32 eq_msix_index); +u32 eq_msix_index,bool *submitted); -int mana_smc_teardown_hwc (struct shm_channel *sc,bool reset_vf); +int mana_smc_teardown_hwc (struct shm_channel *sc,bool reset_vf, +bool *setup_active);#endif /* _SHM_CHANNEL_H */
Signature · 1 line
2.43.0
[email protected]
AI reviewRe: [PATCH net-next v6 1/4] net: mana: prepare HWC ownership for safe reinitialization
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider: - [High] net: mana: Use-After-Free of CQ during queue teardown due to missing RCU grace period --
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] net: mana: Use-After-Free of CQ during queue teardown due to missing RCU grace period --
commit 50d2c3c4bc7f5e569d234a68a7842e4c466d0022
Author: Long Li <[email protected]>
net: mana: prepare HWC ownership for safe reinitialization
Dynamic HWC queue sizing tears down the bootstrap queues and establishes a second channel before publishing it. Prepare the existing HWC ownership and teardown paths so that sequence cannot free or reuse state still reachable by either the PF or an EQ handler.
Quoted 4 lines
drivers/net/ethernet/microsoft/mana/gdma_main.c +0
-0
[ ... ]
Quoted 7 lines
drivers/net/ethernet/microsoft/mana/gdma_main.c +2
-1@@ -922,11 +923,16 @@ static void mana_gd_process_eqe(struct gdma_queue *eq)switch (type) {case GDMA_EQE_COMPLETION : cq_id = eqe->details[0 ] &0xFFFFFF ; -if (WARN_ON_ONCE (cq_id >= gc->max_num_cqs)) +/* The IRQ handler's RCU read-side section protects the table +* until HWC teardown has fenced its EQ and waited for readers.
drivers/net/ethernet/microsoft/mana/gdma_main.c static void mana_gd_process_eqe(struct gdma_queue *eq) · line 935
Quoted 10 lines
drivers/net/ethernet/microsoft/mana/gdma_main.c +6
-2+*/ + cq_table =smp_load_acquire (&gc->cq_table); +if (!cq_table || cq_id >=READ_ONCE (gc->max_num_cqs))break ; - cq = gc->cq_table[cq_id]; -if (WARN_ON_ONCE (!cq || cq->type !=GDMA_CQ || cq->id != cq_id)) + cq =READ_ONCE (cq_table[cq_id]); +if (!cq ||WARN_ON_ONCE (cq->type !=GDMA_CQ || + cq->id != cq_id))
[Severity: High]
Can this dereference of cq race with mana_gd_destroy_queue() and cause a use-after-free?
When the network device is detached (e.g., driver unload or suspend), mana_dealloc_queues() destroys Ethernet CQs via mana_destroy_rxqs() and mana_destroy_txq() before destroying the Ethernet EQs via mana_destroy_eq().
Because the Ethernet EQ handler is still active, its IRQ handler (mana_gd_process_eqe()) can run concurrently. Inside the RCU read-side critical section, mana_gd_process_eqe() reads the CQ pointer from cq_table.
If the pointer is read just before it is unpublished, the subsequent cq->type dereference will access memory that is immediately freed by mana_gd_destroy_queue():
drivers/net/ethernet/microsoft/mana/gdma_main.c:mana_gd_destroy_queue() {
...
mana_gd_free_memory(gmi);
kfree(queue);
}The kfree(queue) here doesn't wait for an RCU grace period (via synchronize_rcu() or kfree_rcu()), allowing the active EQ handler to access freed memory.
Quoted 3 lines
drivers/net/ethernet/microsoft/mana/gdma_main.c +0
-0break ;if (cq->cq.callback)
Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=1
Re: [PATCH net-next v6 1/4] net: mana: prepare HWC ownership for safe reinitialization
Quoted 2 lines · On Thu, Oct 08, 2026 at 12:54:01PM +0000, [email protected] wrote:
Can this dereference of cq race with
mana_gd_destroy_queue()and cause a use-after-free?
Thanks for the review. I agree that the Ethernet CQ lifetime gap described here needs to be fixed. However, it is already present on the base of this series, c66d93e68728, rather than introduced by this patch.
On that base, mana_gd_destroy_cq() clears the CQ table entry without waiting for existing readers, and mana_gd_destroy_queue() subsequently frees the queue. Both functions and the Ethernet CQ-before-EQ teardown order are unchanged by this series. The original completion handler also obtained the CQ pointer and dereferenced it without a corresponding reclamation grace period.
The reader changes here serve a different purpose: the acquire-load of gc->cq_table pairs with HWC's release-publication of the initialized table and its bound, while the NULL checks handle an unpublished table or entry. They do not provide lifetime protection for an Ethernet CQ that another CPU has already obtained from the table.
For HWC specifically, this patch destroys its dedicated EQ before freeing the CQ and callback state. EQ deregistration removes the EQ from the IRQ dispatch list and calls synchronize_rcu(), draining the existing IRQ-side readers before the HWC CQ is released. This does not protect the separate Ethernet CQ teardown path described in the report.
The reported CQ-destruction path is fixed in an independent MANA queue-set replacement series that I plan to post shortly. That change unpublishes the exact CQ pointer and waits for existing IRQ-side RCU readers before the CQ is freed. It adds teardown-side synchronization without adding per-completion reference counting.
I am keeping that pre-existing-bug fix in the independent series rather than expanding the scope of this HWC concurrency and queue-depth series.
Thanks,
Wei
PATCH v6 2/4 net: mana: give each HWC message slot its own completion state
In reply to Wei HuFrom: Long Li <[email protected]>
Concurrent requests require the response handler and the waiting sender to agree on the lifetime and result state of each message slot.
Protect the caller's output buffer, Linux error and device status with a per-slot lock. Publish the output buffer only while the sender is waiting and withdraw it before every return. A late response therefore cannot copy through a pointer to caller storage whose lifetime has ended.
Reinitialize completion and result state when the slot is acquired. If the response records its result while the timed wait expires, return that result instead of reporting a false timeout.
HWC responses contain only the slot ID. After a genuine timeout, prevent the serialized bootstrap channel from reusing that ID until teardown. This keeps a stale response from completing a later request before the next patch replaces the depth-one latch with per-slot sender and response ownership.
Split response-status handling and request cleanup into helpers so the send path has structured returns rather than phase-jumping gotos.
--- .../net/ethernet/microsoft/mana/hw_channel.c | 134 +++++++++++++----- include/net/mana/hw_channel.h | 7 +- 2 files changed, 106 insertions(+), 35 deletions(-)
drivers/net/ethernet/microsoft/mana/hw_channel.c +100 -34
@@ -9,6 +9,7 @@static int mana_hwc_get_msg_index (struct hw_channel_context *hwc,u16 *msg_id) {struct gdma_resource *r = &hwc->inflight_msg_res; +struct hwc_caller_ctx *ctx;unsigned long flags;u32 index;
@@ -16,9 +17,22 @@ static int mana_hwc_get_msg_index(struct hw_channel_context *hwc, u16 *msg_id)spin_lock_irqsave (&r->lock, flags); +if (hwc->hwc_timed_out) { +spin_unlock_irqrestore (&r->lock, flags); +up (&hwc->sema); +return -ETIMEDOUT ; + } + index =find_first_zero_bit (hwc->inflight_msg_res.map, hwc->inflight_msg_res.size); + ctx = &hwc->caller_ctx[index]; +reinit_completion (&ctx->comp_event); + ctx->output_buf =NULL ; + ctx->output_buflen =0 ; + ctx->error = -EINPROGRESS ; + ctx->status_code =0 ; +bitmap_set (hwc->inflight_msg_res.map, index,1 );spin_unlock_irqrestore (&r->lock, flags);
@@ -28,12 +42,15 @@ static int mana_hwc_get_msg_index(struct hw_channel_context *hwc, u16 *msg_id)return 0 ; } -static void mana_hwc_put_msg_index (struct hw_channel_context *hwc,u16 msg_id) +static void mana_hwc_put_msg_index (struct hw_channel_context *hwc,u16 msg_id, +bool timed_out) {struct gdma_resource *r = &hwc->inflight_msg_res;unsigned long flags;spin_lock_irqsave (&r->lock, flags); +if (timed_out) + hwc->hwc_timed_out = true;bitmap_clear (hwc->inflight_msg_res.map, msg_id,1 );spin_unlock_irqrestore (&r->lock, flags);
@@ -90,14 +107,21 @@ static void mana_hwc_handle_resp(struct hw_channel_context *hwc, u32 resp_len, } ctx = hwc->caller_ctx + msg_id; - err =mana_hwc_verify_resp_msg (ctx, resp_msg, resp_len); -if (err) - goto out; - ctx->status_code = resp_msg->status; +spin_lock (&ctx->lock); +if (!ctx->output_buf) { +spin_unlock (&ctx->lock); +mana_hwc_post_rx_wqe (hwc->rxq, rx_req); +return ; + } -memcpy (ctx->output_buf, resp_msg, resp_len); -out: + err =mana_hwc_verify_resp_msg (ctx, resp_msg, resp_len); +if (!err) { + ctx->status_code = resp_msg->status; +memcpy (ctx->output_buf, resp_msg, resp_len); + } + + ctx->output_buf =NULL ; ctx->error = err;/* Must post rx wqe before complete(), otherwise the next rx may
@@ -106,6 +130,7 @@ static void mana_hwc_handle_resp(struct hw_channel_context *hwc, u32 resp_len,mana_hwc_post_rx_wqe (hwc->rxq, rx_req);complete (&ctx->comp_event); +spin_unlock (&ctx->lock); } static void mana_hwc_init_event_handler(void *ctx, struct gdma_queue *q_self,
@@ -694,8 +719,10 @@ static int mana_hwc_test_channel(struct hw_channel_context *hwc, u16 q_depth,if (!ctx)return -ENOMEM ; -for (i =0 ; i < q_depth; ++i) +for (i =0 ; i < q_depth; ++i) {init_completion (&ctx[i].comp_event); +spin_lock_init (&ctx[i].lock); + } hwc->caller_ctx = ctx;
@@ -958,6 +985,38 @@ void mana_hwc_destroy_channel(struct gdma_context *gc)vfree (old_cq_table); } +static int mana_hwc_response_status (struct hw_channel_context *hwc, +u32 command,int error,u32 status) +{ +if (error) +return error; + +if (!status || status ==GDMA_STATUS_MORE_ENTRIES ) +return 0 ; + +if (status ==GDMA_STATUS_CMD_UNSUPPORTED ) +return -EOPNOTSUPP ; + +if (command !=MANA_QUERY_PHY_STAT ) +dev_err (hwc->dev,"Command 0x%x failed with status: 0x%x\n" , + command, status); + +return -EPROTO ; +} + +static void mana_hwc_finish_request (struct hw_channel_context *hwc, +struct hwc_caller_ctx *ctx,u16 msg_id, +bool timed_out) +{ +unsigned long flags; + +spin_lock_irqsave (&ctx->lock, flags); + ctx->output_buf =NULL ; +spin_unlock_irqrestore (&ctx->lock, flags); + +mana_hwc_put_msg_index (hwc, msg_id, timed_out); +} +int mana_hwc_send_request (struct hw_channel_context *hwc,u32 req_len,const void *req,u32 resp_len,void *resp) {
@@ -965,26 +1024,32 @@ int mana_hwc_send_request(struct hw_channel_context *hwc, u32 req_len,struct hwc_wq *txq = hwc->txq;struct gdma_req_hdr *req_msg;struct hwc_caller_ctx *ctx; +unsigned long flags;u32 dest_vrcq;u32 dest_vrq;u32 command; +u32 status;u16 msg_id;int err; -mana_hwc_get_msg_index (hwc, &msg_id); + err =mana_hwc_get_msg_index (hwc, &msg_id); +if (err) +return err; tx_wr = &txq->msg_buf->reqs[msg_id]; + ctx = hwc->caller_ctx + msg_id;if (req_len > tx_wr->buf_len) {dev_err (hwc->dev,"HWC: req msg size: %d > %d\n" , req_len, tx_wr->buf_len); - err = -EINVAL ; - goto out; +mana_hwc_finish_request (hwc, ctx, msg_id, false); +return -EINVAL ; } - ctx = hwc->caller_ctx + msg_id; +spin_lock_irqsave (&ctx->lock, flags); ctx->output_buf = resp; ctx->output_buflen = resp_len; +spin_unlock_irqrestore (&ctx->lock, flags); req_msg = (struct gdma_req_hdr *)tx_wr->buf_va;if (req)
@@ -1006,11 +1071,23 @@ int mana_hwc_send_request(struct hw_channel_context *hwc, u32 req_len, err =mana_hwc_post_tx_wqe (txq, tx_wr, dest_vrq, dest_vrcq, false);if (err) {dev_err (hwc->dev,"HWC: Failed to post send WQE: %d\n" , err); - goto out; +mana_hwc_finish_request (hwc, ctx, msg_id, false); +return err; }if (!wait_for_completion_timeout (&ctx->comp_event, - (msecs_to_jiffies (hwc->hwc_timeout)))) { +msecs_to_jiffies (hwc->hwc_timeout))) { +spin_lock_irqsave (&ctx->lock, flags); + ctx->output_buf =NULL ; + err = ctx->error; + status = ctx->status_code; +spin_unlock_irqrestore (&ctx->lock, flags); + +if (err != -EINPROGRESS ) { +mana_hwc_finish_request (hwc, ctx, msg_id, false); +return mana_hwc_response_status (hwc, command, err, status); + } +if (hwc->hwc_timeout !=0 )dev_err (hwc->dev,"Command 0x%x timed out: %u ms\n" , command, hwc->hwc_timeout);
@@ -1019,27 +1096,16 @@ int mana_hwc_send_request(struct hw_channel_context *hwc, u32 req_len,if (hwc->hwc_timeout >1 ) hwc->hwc_timeout =1 ; - err = -ETIMEDOUT ; - goto out; +mana_hwc_finish_request (hwc, ctx, msg_id, true); +return -ETIMEDOUT ; } -if (ctx->error) { - err = ctx->error; - goto out; - } +spin_lock_irqsave (&ctx->lock, flags); + ctx->output_buf =NULL ; + err = ctx->error; + status = ctx->status_code; +spin_unlock_irqrestore (&ctx->lock, flags); -if (ctx->status_code && ctx->status_code !=GDMA_STATUS_MORE_ENTRIES ) { -if (ctx->status_code ==GDMA_STATUS_CMD_UNSUPPORTED ) { - err = -EOPNOTSUPP ; - goto out; - } -if (command !=MANA_QUERY_PHY_STAT ) -dev_err (hwc->dev,"Command 0x%x failed with status: 0x%x\n" , - command, ctx->status_code); - err = -EPROTO ; - goto out; - } -out: -mana_hwc_put_msg_index (hwc, msg_id); -return err; +mana_hwc_finish_request (hwc, ctx, msg_id, false); +return mana_hwc_response_status (hwc, command, err, status); }
include/net/mana/hw_channel.h +6 -1
@@ -168,10 +168,12 @@ struct hwc_wq {struct hwc_caller_ctx {struct completion comp_event; +/* Protects the output buffer and response state from timeout. */ +spinlock_t lock;void *output_buf;u32 output_buflen; -u32 error;/* Linux error code */ +int error;/* Linux error code */ u32 status_code; };
@@ -201,6 +203,9 @@ struct hw_channel_context {u32 dest_vrcq_id;u32 hwc_timeout; +/* Prevents message ID reuse after a timeout; protected by the map lock. */ +bool hwc_timed_out; +/* The PF may own the HWC queues while this is true. */ bool setup_active;struct hwc_caller_ctx *caller_ctx;
Signature · 1 line
2.43.0
[email protected]
AI reviewRe: [PATCH net-next v6 2/4] net: mana: give each HWC message slot its own completion state
Sashiko has reviewed this patch and found no issues. It looks great!
Quoted 20 lines
From: Long Li <[email protected]>
Concurrent requests require the response handler and the waiting sender to agree on the lifetime and result state of each message slot.
Protect the caller's output buffer, Linux error and device status with a per-slot lock. Publish the output buffer only while the sender is waiting and withdraw it before every return. A late response therefore cannot copy through a pointer to caller storage whose lifetime has ended.
Reinitialize completion and result state when the slot is acquired. If the response records its result while the timed wait expires, return that result instead of reporting a false timeout.
HWC responses contain only the slot ID. After a genuine timeout, prevent the serialized bootstrap channel from reusing that ID until teardown. This keeps a stale response from completing a later request before the next patch replaces the depth-one latch with per-slot sender and response ownership.
Quoted 7 lines
Split response-status handling and request cleanup into helpers so the send path has structured returns rather than phase-jumping gotos.
Signed-off-by Long Li <[email protected]>Signed-off-by Wei Hu <[email protected]>
Sashiko has reviewed this patch and found no issues. It looks great!
Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=2
PATCH v6 3/4 net: mana: support concurrent HWC requests
In reply to Wei HuFrom: Long Li <[email protected]>
Replace the depth-one timeout latch with per-slot sender and response ownership. Initialize each slot under the inflight resource lock, publish its bitmap bit last, and release it only after both sides have finished. This preserves response-buffer withdrawal and timeout quarantine while allowing independent message IDs to make progress.
Serialize SQ posting so concurrent senders cannot corrupt the producer state. A posted request which times out keeps its response reference and admission permit until its late response arrives or teardown cancels it.
Return -EBUSY when all slots remain occupied. Admission pressure is not a response timeout and must not make callers start dead-channel recovery.
Synchronize hwc_timeout updates with atomic access helpers. Teardown cancellation is terminal for a channel instance, firmware and query updates may replace only a live timeout, and fail-fast reduction may only lower a live value to one millisecond.
Keep setup private until the queues, admission state, caller contexts and direct EQ test are ready. Runtime teardown unpublishes the channel, rejects new admissions, wakes waiters and drains active senders before releasing or retaining PF-owned mappings.
Split admission, submission, waiting, response status and unwind into helpers so mana_hwc_send_request() uses structured returns instead of phase-jumping gotos.
--- .../net/ethernet/microsoft/mana/gdma_main.c | 80 ++- .../net/ethernet/microsoft/mana/hw_channel.c | 578 +++++++++++++----- include/net/mana/gdma.h | 9 + include/net/mana/hw_channel.h | 43 +- 4 files changed, 527 insertions(+), 183 deletions(-)
drivers/net/ethernet/microsoft/mana/gdma_main.c +67 -13
@@ -162,6 +162,8 @@ static int mana_gd_init_registers(struct pci_dev *pdev)bool mana_need_log (struct gdma_context *gc,int err) {struct hw_channel_context *hwc; +bool need_log = true; +unsigned long flags;if (err != -ETIMEDOUT )return true;
@@ -169,11 +171,13 @@ bool mana_need_log(struct gdma_context *gc, int err)if (!gc)return true; +spin_lock_irqsave (&gc->hwc_lock, flags); hwc = gc->hwc.driver_data; -if (hwc && hwc->hwc_timeout ==0 ) -return false; +if (hwc && !mana_hwc_timeout_read (hwc)) + need_log = false; +spin_unlock_irqrestore (&gc->hwc_lock, flags); -return true; +return need_log; }static int mana_gd_query_max_resources (struct pci_dev *pdev)
@@ -317,7 +321,8 @@ static int mana_gd_query_max_resources(struct pci_dev *pdev)return 0 ; } -static int mana_gd_query_hwc_timeout (struct pci_dev *pdev,u32 *timeout_val) +static int mana_gd_query_hwc_timeout (struct pci_dev *pdev,u32 timeout_ms, +u32 *new_timeout_ms) {struct gdma_context *gc =pci_get_drvdata (pdev);struct gdma_query_hwc_timeout_resp resp = {};
@@ -326,12 +331,12 @@ static int mana_gd_query_hwc_timeout(struct pci_dev *pdev, u32 *timeout_val)mana_gd_init_req_hdr (&req.hdr,GDMA_QUERY_HWC_TIMEOUT ,sizeof (req),sizeof (resp)); - req.timeout_ms = *timeout_val; + req.timeout_ms = timeout_ms; err =mana_gd_send_request (gc,sizeof (req), &req,sizeof (resp), &resp);if (err || resp.hdr.status)return err ? err : -EPROTO ; - *timeout_val = resp.timeout_ms; + *new_timeout_ms = resp.timeout_ms;return 0 ; }
@@ -387,9 +392,27 @@ static int mana_gd_detect_devices(struct pci_dev *pdev)int mana_gd_send_request (struct gdma_context *gc,u32 req_len,const void *req,u32 resp_len,void *resp) { -struct hw_channel_context *hwc = gc->hwc.driver_data; +struct hw_channel_context *hwc; +unsigned long flags; +int err; + +spin_lock_irqsave (&gc->hwc_lock, flags); + hwc = gc->hwc.driver_data; +if (!hwc) { +spin_unlock_irqrestore (&gc->hwc_lock, flags); +return -ENODEV ; + } + hwc->active_senders++; +spin_unlock_irqrestore (&gc->hwc_lock, flags); -return mana_hwc_send_request (hwc, req_len, req, resp_len, resp); + err =mana_hwc_send_request (hwc, req_len, req, resp_len, resp); + +spin_lock_irqsave (&gc->hwc_lock, flags); +if (--hwc->active_senders ==0 ) +wake_up (&gc->hwc_drain_waitq); +spin_unlock_irqrestore (&gc->hwc_lock, flags); + +return err; }EXPORT_SYMBOL_NS (mana_gd_send_request,"NET_MANA" );
@@ -710,6 +733,7 @@ static void mana_serv_reset(struct pci_dev *pdev) {struct gdma_context *gc =pci_get_drvdata (pdev);struct hw_channel_context *hwc; +unsigned long flags;int ret;if (!gc) {
@@ -719,14 +743,17 @@ static void mana_serv_reset(struct pci_dev *pdev)return ; } +spin_lock_irqsave (&gc->hwc_lock, flags); hwc = gc->hwc.driver_data;if (!hwc) { +spin_unlock_irqrestore (&gc->hwc_lock, flags);dev_err (&pdev->dev,"MANA service: no HWC\n" ); goto out; }/* HWC is not responding in this case, so don't wait */ - hwc->hwc_timeout =0 ; +mana_hwc_timeout_cancel (hwc); +spin_unlock_irqrestore (&gc->hwc_lock, flags);dev_info (&pdev->dev,"MANA reset cycle start\n" );
@@ -1107,7 +1134,9 @@ static void mana_gd_deregister_irq(struct gdma_queue *queue)synchronize_rcu (); } -int mana_gd_test_eq (struct gdma_context *gc,struct gdma_queue *eq) +static int mana_gd_test_eq_request (struct gdma_context *gc, +struct hw_channel_context *hwc, +struct gdma_queue *eq) {struct gdma_generate_test_event_req req = {};struct gdma_general_resp resp = {};
@@ -1125,7 +1154,12 @@ int mana_gd_test_eq(struct gdma_context *gc, struct gdma_queue *eq) req.hdr.dev_id = eq->gdma_dev->dev_id; req.queue_index = eq->id; - err =mana_gd_send_request (gc,sizeof (req), &req,sizeof (resp), &resp); +if (hwc) + err =mana_hwc_send_request (hwc,sizeof (req), &req, +sizeof (resp), &resp); +else + err =mana_gd_send_request (gc,sizeof (req), &req, +sizeof (resp), &resp);if (err) {if (mana_need_log (gc, err))dev_err (dev,"test_eq failed: %d\n" , err);
@@ -1156,6 +1190,17 @@ int mana_gd_test_eq(struct gdma_context *gc, struct gdma_queue *eq)return err; } +int mana_gd_test_eq (struct gdma_context *gc,struct gdma_queue *eq) +{ +return mana_gd_test_eq_request (gc,NULL , eq); +} + +int mana_gd_test_hwc_eq (struct hw_channel_context *hwc, +struct gdma_queue *eq) +{ +return mana_gd_test_eq_request (hwc->gdma_dev->gdma_context, hwc, eq); +} +static void mana_gd_destroy_eq (struct gdma_context *gc,bool flush_events,struct gdma_queue *queue) {
@@ -1348,6 +1393,7 @@ static int mana_gd_create_dma_region(struct gdma_dev *gd,if (gmi->nr_pages ==0 && !MANA_PAGE_ALIGNED (gmi->virt_addr))return -EINVAL ; +/* The caller must keep the HWC alive throughout queue creation. */ hwc = gc->hwc.driver_data; req_msg_size =struct_size (req, page_addr_list, num_page);if (req_msg_size > hwc->max_req_msg_size)
@@ -1551,9 +1597,12 @@ int mana_gd_verify_vf_version(struct pci_dev *pdev)struct gdma_verify_ver_resp resp = {};struct gdma_verify_ver_req req = {};struct hw_channel_context *hwc; +u32 timeout_ms;int err; +/* The setup caller must exclude concurrent HWC teardown. */ hwc = gc->hwc.driver_data; +mana_gd_init_req_hdr (&req.hdr,GDMA_VERIFY_VF_DRIVER_VERSION ,sizeof (req),sizeof (resp));
@@ -1589,12 +1638,16 @@ int mana_gd_verify_vf_version(struct pci_dev *pdev) &gc->pf_cap_flags1);if (resp.pf_cap_flags1 &GDMA_DRV_CAP_FLAG_1_HWC_TIMEOUT_RECONFIG ) { - err =mana_gd_query_hwc_timeout (pdev, &hwc->hwc_timeout); + err =mana_gd_query_hwc_timeout (pdev, +mana_hwc_timeout_read (hwc), + &timeout_ms);if (err) {dev_err (gc->dev,"Failed to set the hwc timeout %d\n" , err);return err; } -dev_dbg (gc->dev,"set the hwc timeout to %u\n" , hwc->hwc_timeout); +mana_hwc_timeout_update (hwc, timeout_ms); +dev_dbg (gc->dev,"set the hwc timeout to %u\n" , +mana_hwc_timeout_read (hwc)); }return 0 ; }
@@ -2547,6 +2600,7 @@ static int mana_gd_probe(struct pci_dev *pdev, const struct pci_device_id *ent)mutex_init (&gc->eq_test_event_mutex);mutex_init (&gc->gic_mutex); +spin_lock_init (&gc->hwc_lock);pci_set_drvdata (pdev, gc); gc->bar0_pa =pci_resource_start (pdev,0 ); gc->bar0_size =pci_resource_len (pdev,0 );
drivers/net/ethernet/microsoft/mana/hw_channel.c +413 -165
800 lines not on this page · raw message
include/net/mana/gdma.h +9 -0
@@ -468,6 +468,15 @@ struct gdma_context {/* Hardware communication channel (HWC) */ struct gdma_dev hwc; +/* Sender drain; the final wakeup runs under hwc_lock. */ +wait_queue_head_t hwc_drain_waitq; + +/* Protects runtime HWC publication and active sender references. +* Setup owns an unpublished HWC directly; timeout updates use atomic +* access helpers and do not require this lock. +*/ +spinlock_t hwc_lock; +/* Azure network adapter */ struct gdma_dev mana;
include/net/mana/hw_channel.h +38 -5
78 lines not on this page · raw message
Signature · 1 line
2.43.0
[email protected]
AI reviewRe: [PATCH net-next v6 3/4] net: mana: support concurrent HWC requests
Sashiko has reviewed this patch and found no issues. It looks great!
Quoted 15 lines
From: Long Li <[email protected]>
Replace the depth-one timeout latch with per-slot sender and response ownership. Initialize each slot under the inflight resource lock, publish its bitmap bit last, and release it only after both sides have finished. This preserves response-buffer withdrawal and timeout quarantine while allowing independent message IDs to make progress.
Serialize SQ posting so concurrent senders cannot corrupt the producer state. A posted request which times out keeps its response reference and admission permit until its late response arrives or teardown cancels it.
Return
-EBUSYwhen all slots remain occupied. Admission pressure is not a response timeout and must not make callers start dead-channel recovery.
Quoted 6 lines
[ ... ]
Signed-off-by Long Li <[email protected]>Signed-off-by Wei Hu <[email protected]>
Sashiko has reviewed this patch and found no issues. It looks great!
Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=3
PATCH v6 4/4 net: mana: add dynamic HWC queue depth with reinit path
In reply to Wei HuFrom: Long Li <[email protected]>
The HWC starts with depth-one bootstrap queues. Treat the PF-reported depth as a maximum and rebuild the channel exactly for reports from 2 through
128. Keep the untouched bootstrap queues for depth one and reports above 128, and require a rebuilt channel to repeat the selected depth.
Treat the reported request and response sizes as directional maxima. Rebuild only when both reports equal the 4096-byte bootstrap allocation, then enforce the effective report/allocation limit on every request and expected response.
Keep each candidate channel private through queue creation, establishment and the direct EQ test. Publish only the final tested channel. If a rebuild fails after acknowledged teardown, destroy that candidate and establish fresh bootstrap queues; never reuse mappings already handed to the PF.
Invalidate the previous HWC doorbell before every ESTABLISH_HWC. Accept a new doorbell only after validating the BAR0 page geometry and reported index, and suppress MMIO while re-establishment leaves the HWC doorbell invalid.
Do not advertise the proposed dynamic-depth capability bit. Driver-version advertisement occurs after HWC establishment and cannot negotiate behavior needed while the channel is being created.
Use focused build, validation, rebuild and fallback helpers instead of the goto-heavy creation flow from v5.
--- .../net/ethernet/microsoft/mana/gdma_main.c | 24 +- .../net/ethernet/microsoft/mana/hw_channel.c | 290 +++++++++++++++--- include/net/mana/gdma.h | 2 + include/net/mana/hw_channel.h | 10 +- 4 files changed, 266 insertions(+), 60 deletions(-)
drivers/net/ethernet/microsoft/mana/gdma_main.c +16 -8
@@ -580,12 +580,26 @@ static int mana_gd_disable_queue(struct gdma_queue *queue)#define DOORBELL_OFFSET_EQ 0xFF8#define DOORBELL_OFFSET_DIM 0x820 +bool mana_gd_is_valid_doorbell (struct gdma_context *gc,u32 db_id) +{ +if (!gc->db_page_size || gc->db_page_off >= gc->bar0_size) +return false; + +return gc->db_page_off + + gc->db_page_size * ((u64 )db_id +1 ) <= gc->bar0_size; +} +static void mana_gd_ring_doorbell (struct gdma_context *gc,u32 db_index,enum gdma_queue_type q_type,u32 qid,u32 tail_ptr,u8 num_req) { -void __iomem *addr = gc->db_page_base + gc->db_page_size * db_index;union gdma_doorbell_entry e = {}; +void __iomem *addr; + +if (unlikely (db_index ==INVALID_DOORBELL )) +return ; + + addr = gc->db_page_base + gc->db_page_size * db_index;switch (q_type) {case GDMA_EQ :
@@ -1675,13 +1689,7 @@ int mana_gd_register_device(struct gdma_dev *gd)return err ? err : -EPROTO ; } -/* Validate that doorbell page for db_id is within the BAR0 region. -* In mana_gd_ring_doorbell(), the address is calculated as: -* addr = db_page_base + db_page_size * db_id -* = (bar0_va + db_page_off) + (db_page_size * db_id) -* So we need: db_page_off + db_page_size * (db_id + 1) <= bar0_size -*/ -if (gc->db_page_off + gc->db_page_size * ((u64 )resp.db_id +1 ) > gc->bar0_size) { +if (!mana_gd_is_valid_doorbell (gc, resp.db_id)) {dev_err (gc->dev,"Doorbell ID %u out of range\n" , resp.db_id);return -EPROTO ; }
drivers/net/ethernet/microsoft/mana/hw_channel.c +239 -51
403 lines not on this page · raw message
include/net/mana/gdma.h +2 -0
@@ -534,6 +534,8 @@ void mana_gd_fence_eq(struct gdma_context *gc, struct gdma_queue *queue);int mana_gd_poll_cq (struct gdma_queue *cq,struct gdma_comp *comp,int num_cqe); +bool mana_gd_is_valid_doorbell (struct gdma_context *gc,u32 db_id); +void mana_gd_ring_cq (struct gdma_queue *cq,u8 arm_bit); ssize_t mana_gd_read_ring(struct gdma_queue *q, char __user *buf,
include/net/mana/hw_channel.h +9 -1
@@ -11,6 +11,9 @@#define HW_CHANNEL_VF_BOOTSTRAP_QUEUE_DEPTH 1 +/* Largest supported rebuild depth; larger reports retain bootstrap queues. */ +#define HW_CHANNEL_MAX_QUEUE_DEPTH 128 +#define HWC_INIT_DATA_CQID 1#define HWC_INIT_DATA_RQID 2#define HWC_INIT_DATA_SQID 3
@@ -198,12 +201,17 @@ struct hw_channel_context {u16 num_inflight_msg;u32 max_req_msg_size; +u32 max_resp_msg_size; +/* Immutable reported maxima for the final RQ and SQ directions. */ +u32 rx_msg_size_limit; +u32 tx_msg_size_limit; -u16 hwc_init_q_depth_max; +u32 hwc_init_q_depth_max;u32 hwc_init_max_req_msg_size;u32 hwc_init_max_resp_msg_size;u32 hwc_init_max_num_cqs;u32 hwc_init_cq_id; +bool hwc_init_doorbell;struct completion hwc_init_eqe_comp;
Signature · 1 line
2.43.0
[email protected]
AI reviewRe: [PATCH net-next v6 4/4] net: mana: add dynamic HWC queue depth with reinit path
Sashiko has reviewed this patch and found no issues. It looks great!
Quoted 18 lines
From: Long Li <[email protected]>
The HWC starts with depth-one bootstrap queues. Treat the PF-reported depth as a maximum and rebuild the channel exactly for reports from 2 through
128. Keep the untouched bootstrap queues for depth one and reports above 128, and require a rebuilt channel to repeat the selected depth.Treat the reported request and response sizes as directional maxima. Rebuild only when both reports equal the 4096-byte bootstrap allocation, then enforce the effective report/allocation limit on every request and expected response.
Keep each candidate channel private through queue creation, establishment and the direct EQ test. Publish only the final tested channel. If a rebuild fails after acknowledged teardown, destroy that candidate and establish [ ... ]
goto-heavy creation flow from v5.
Quoted 3 lines
Signed-off-by Long Li <[email protected]>Signed-off-by Wei Hu <[email protected]>
Sashiko has reviewed this patch and found no issues. It looks great!
Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=4
Simon Horman
reviewerOn Wed, Oct 07, 2026 at 12:53:26PM +0000, Wei Hu wrote:
...
Quoted 5 lines
Long Li (4):
net: mana: prepare HWC ownership for safe reinitialization
net: mana: give each HWC message slot its own completion state
net: mana: support concurrent HWC requests
net: mana: add dynamic HWC queue depth with reinit path
Hi Wei,
Unfortunately this patch-set did not apply cleanly to net-next, and thus our CI did not run.
Please rebase and repost.
...
Signature · 1 line
pw-bot: changes-requested
Wei Hu
maintainerQuoted 41 lines
-----Original Message-----
From: Simon Horman <[email protected]>
Sent: Friday, October 9, 2026 11:19 PM
To: Wei Hu <[email protected]>
Cc: Long Li <[email protected]>; Konstantin Taranov <[email protected]>; Jakub Kicinski <[email protected]>; David S. Miller <[email protected]>; Paolo Abeni <[email protected]>; Eric Dumazet <[email protected]>; Andrew Lunn <[email protected]>; Jason Gunthorpe <[email protected]>; Leon Romanovsky <[email protected]>; Haiyang Zhang <[email protected]>; K. Y. Srinivasan <[email protected]>; Wei Liu <[email protected]>; Dexuan Cui <[email protected]>; Shradha Gupta <[email protected]>; Erni Sri Satya Vennela <[email protected]>; Stephen Hemminger <[email protected]>; Shiraz Saleem <[email protected]>; [email protected]; linux- [email protected]; [email protected]; linux- [email protected]; Aditya Garg <[email protected]>; Dipayaan Roy <[email protected]>; Kees Cook <[email protected]>; Kees Cook <[email protected]>; Manish Awasthi <[email protected]>; Wei Hu <[email protected]>
Subject: [EXTERNAL] Re: [PATCH net-next v6 0/4] net: mana: concurrent HWC requests and dynamic queue depthOn Wed, Oct 07, 2026 at 12:53:26PM +0000, Wei Hu wrote:
...
Quoted 5 lines
Long Li (4):
net: mana: prepare HWC ownership for safe reinitialization
net: mana: give each HWC message slot its own completion state
net: mana: support concurrent HWC requests
net: mana: add dynamic HWC queue depth with reinit pathHi Wei,
Unfortunately this patch-set did not apply cleanly to net-next, and thus our CI did not run.
Quoted 6 lines
Please rebase and repost.
...
--
pw-bot: changes-requested
Hi Simon,
Thanks. I will send the rebased v7 soon.
Wei