diff options
| author | Jakub Kicinski <kuba@kernel.org> | 2026-06-09 17:23:42 -0700 |
|---|---|---|
| committer | Jakub Kicinski <kuba@kernel.org> | 2026-06-09 17:25:11 -0700 |
| commit | 81a699ccd3091915d00da847df8dac0d1b131693 (patch) | |
| tree | 0d343538a8be2a196665ab0ef4ea3f55ef0775b1 /include | |
| parent | 5c9a6a124afdb933b3f2c9cd685f729920da0a37 (diff) | |
| parent | 062b2b051f14a974b1fbd7b506fb833f5a171fa8 (diff) | |
Merge branch 'mana-per-vport-eq'
Long Li says:
====================
net: mana: Per-vPort EQ and MSI-X management
This series moves EQ ownership from the shared mana_context to per-vPort
mana_port_context, enabling each vPort to have dedicated MSI-X vectors
when the hardware provides enough vectors. When vectors are limited, the
driver falls back to sharing MSI-X among vPorts.
The series introduces a GDMA IRQ Context (GIC) abstraction with reference
counting to manage interrupt context lifecycle. This allows both Ethernet
and RDMA EQs to dynamically acquire dedicated or shared MSI-X vectors at
vPort creation time rather than pre-allocating all vectors at probe time.
====================
Link: https://patch.msgid.link/20260605005717.2059954-1-longli@microsoft.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'include')
| -rw-r--r-- | include/net/mana/gdma.h | 33 | ||||
| -rw-r--r-- | include/net/mana/mana.h | 15 |
2 files changed, 42 insertions, 6 deletions
diff --git a/include/net/mana/gdma.h b/include/net/mana/gdma.h index 70d62bc32837..78afd696b08b 100644 --- a/include/net/mana/gdma.h +++ b/include/net/mana/gdma.h @@ -342,6 +342,7 @@ struct gdma_queue { void *context; unsigned int msix_index; + unsigned int irq; u32 log2_throttle_limit; } eq; @@ -388,6 +389,11 @@ struct gdma_irq_context { spinlock_t lock; struct list_head eq_list; char name[MANA_IRQ_NAME_SZ]; + unsigned int msi; + unsigned int irq; + refcount_t refcount; + unsigned int bitmap_refs; + bool dyn_msix; }; enum gdma_context_flags { @@ -399,8 +405,10 @@ struct gdma_context { struct device *dev; struct dentry *mana_pci_debugfs; - /* Per-vPort max number of queues */ + /* Hardware max number of queues */ unsigned int max_num_queues; + /* Per-vPort max number of queues */ + unsigned int max_num_queues_vport; unsigned int max_num_msix; unsigned int num_msix_usable; struct xarray irq_contexts; @@ -447,6 +455,15 @@ struct gdma_context { struct workqueue_struct *service_wq; unsigned long flags; + + /* Protect access to GIC context */ + struct mutex gic_mutex; + + /* Indicate if this device is sharing MSI for EQs on MANA */ + bool msi_sharing; + + /* Bitmap tracks where MSI is allocated when it is not shared for EQs */ + unsigned long *msi_bitmap; }; static inline bool mana_gd_is_mana(struct gdma_dev *gd) @@ -599,6 +616,7 @@ enum { #define GDMA_DRV_CAP_FLAG_1_HWC_TIMEOUT_RECONFIG BIT(3) #define GDMA_DRV_CAP_FLAG_1_GDMA_PAGES_4MB_1GB_2GB BIT(4) #define GDMA_DRV_CAP_FLAG_1_VARIABLE_INDIRECTION_TABLE_SUPPORT BIT(5) +#define GDMA_DRV_CAP_FLAG_1_HW_VPORT_LINK_AWARE BIT(6) /* Driver can handle holes (zeros) in the device list */ #define GDMA_DRV_CAP_FLAG_1_DEV_LIST_HOLES_SUP BIT(11) @@ -615,7 +633,8 @@ enum { /* Driver detects stalled send queues and recovers them */ #define GDMA_DRV_CAP_FLAG_1_HANDLE_STALL_SQ_RECOVERY BIT(18) -#define GDMA_DRV_CAP_FLAG_1_HW_VPORT_LINK_AWARE BIT(6) +/* Driver supports separate EQ/MSIs for each vPort */ +#define GDMA_DRV_CAP_FLAG_1_EQ_MSI_UNSHARE_MULTI_VPORT BIT(19) /* Driver supports linearizing the skb when num_sge exceeds hardware limit */ #define GDMA_DRV_CAP_FLAG_1_SKB_LINEARIZE BIT(20) @@ -643,7 +662,8 @@ enum { GDMA_DRV_CAP_FLAG_1_SKB_LINEARIZE | \ GDMA_DRV_CAP_FLAG_1_PROBE_RECOVERY | \ GDMA_DRV_CAP_FLAG_1_HANDLE_STALL_SQ_RECOVERY | \ - GDMA_DRV_CAP_FLAG_1_HWC_TIMEOUT_RECOVERY) + GDMA_DRV_CAP_FLAG_1_HWC_TIMEOUT_RECOVERY | \ + GDMA_DRV_CAP_FLAG_1_EQ_MSI_UNSHARE_MULTI_VPORT) #define GDMA_DRV_CAP_FLAGS2 0 @@ -1019,4 +1039,11 @@ int mana_gd_resume(struct pci_dev *pdev); bool mana_need_log(struct gdma_context *gc, int err); +struct gdma_irq_context *mana_gd_get_gic(struct gdma_context *gc, + bool use_msi_bitmap, + int *msi_requested); +void mana_gd_put_gic(struct gdma_context *gc, bool use_msi_bitmap, int msi); +int mana_gd_query_device_cfg(struct gdma_context *gc, u32 proto_major_ver, + u32 proto_minor_ver, u32 proto_micro_ver, + u16 *max_num_vports, u8 *bm_hostmode); #endif /* _GDMA_H */ diff --git a/include/net/mana/mana.h b/include/net/mana/mana.h index d9c27310fd04..5a9b94e0ef34 100644 --- a/include/net/mana/mana.h +++ b/include/net/mana/mana.h @@ -480,8 +480,6 @@ struct mana_context { u8 bm_hostmode; struct mana_ethtool_hc_stats hc_stats; - struct mana_eq *eqs; - struct dentry *mana_eqs_debugfs; struct workqueue_struct *per_port_queue_reset_wq; /* Workqueue for querying hardware stats */ struct delayed_work gf_stats_work; @@ -501,6 +499,9 @@ struct mana_port_context { u8 mac_addr[ETH_ALEN]; + struct mana_eq *eqs; + struct dentry *mana_eqs_debugfs; + enum TRI_STATE rss_state; mana_handle_t default_rxobj; @@ -547,6 +548,12 @@ struct mana_port_context { struct mutex vport_mutex; int vport_use_count; + /* Set by mana_set_channels() under vport_mutex to block RDMA + * from grabbing the vport during the detach/attach window. + * Checked by mana_cfg_vport() when called from the RDMA path. + */ + bool channel_changing; + /* Net shaper handle*/ struct net_shaper_handle handle; @@ -1040,8 +1047,10 @@ void mana_destroy_wq_obj(struct mana_port_context *apc, u32 wq_type, mana_handle_t wq_obj); int mana_cfg_vport(struct mana_port_context *apc, u32 protection_dom_id, - u32 doorbell_pg_id); + u32 doorbell_pg_id, bool check_channel_changing); void mana_uncfg_vport(struct mana_port_context *apc); +int mana_create_eq(struct mana_port_context *apc); +void mana_destroy_eq(struct mana_port_context *apc); struct net_device *mana_get_primary_netdev(struct mana_context *ac, u32 port_index, |
