Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
7368530
gve: Define config structs for queue allocation
shreeya-patel98 Jul 23, 2026
2a2055e
gve: Refactor napi add and remove functions
kerneltoast Aug 11, 2026
b41e7b2
gve: Switch to config-aware queue allocation
shailend-g Jan 22, 2024
4aee4e7
gve: Refactor gve_open and gve_close
shreeya-patel98 Jul 24, 2026
691e9d2
gve: Alloc before freeing when adjusting queues
shreeya-patel98 Jul 24, 2026
38b2e74
gve: Alloc before freeing when changing features
shreeya-patel98 Jul 24, 2026
715a5ae
gve: simplify setting decriptor count defaults
shreeya-patel98 Jul 24, 2026
86bfafd
gve: make the completion and buffer ring size equal for DQO
shreeya-patel98 Jul 24, 2026
675099f
gve: set page count for RX QPL for GQI and DQO queue formats
shreeya-patel98 Jul 24, 2026
c5d20e7
gve: add support to read ring size ranges from the device
shreeya-patel98 Jul 24, 2026
5e7756d
gve: add support to change ring size via ethtool
shreeya-patel98 Jul 24, 2026
dedcdef
gve: Fix use of netif_carrier_ok()
praveenkaligineedi Aug 1, 2024
d207a12
gve: Remove unused declaration gve_rx_alloc_rings()
Aug 16, 2024
ea33950
gve: clean XDP queues in gve_tx_stop_ring_gqi
shreeya-patel98 Aug 4, 2026
3150349
gve: fix XDP allocation path in edge cases
josh8551021 Dec 18, 2024
9eb64d4
gve: prevent ethtool ops after shutdown
shreeya-patel98 Aug 4, 2026
66f11ba
gve: defer interrupt enabling until NAPI registration
agarg2008 Aug 12, 2026
02d9272
gve: fix incorrect buffer cleanup in gve_tx_clean_pending_packets for…
agarg2008 Aug 12, 2026
c8811e1
gve: Update QPL page registration logic
shreeya-patel98 Jul 24, 2026
e688544
gve: Enable reading max ring size from the device in DQO-QPL mode
shreeya-patel98 Jul 24, 2026
c5109fe
gve: bound DQO-QPL TX buffer count to the s16 free-list range
shreeya-patel98 Aug 11, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
176 changes: 122 additions & 54 deletions drivers/net/ethernet/google/gve/gve.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@
/* PTYPEs are always 10 bits. */
#define GVE_NUM_PTYPES 1024

/* Default minimum ring size */
#define GVE_DEFAULT_MIN_TX_RING_SIZE 256
#define GVE_DEFAULT_MIN_RX_RING_SIZE 512

#define GVE_DEFAULT_RX_BUFFER_SIZE 2048

#define GVE_DEFAULT_RX_BUFFER_OFFSET 2048
Expand All @@ -56,9 +60,6 @@

#define GVE_GQ_TX_MIN_PKT_DESC_BYTES 182

#define DQO_QPL_DEFAULT_TX_PAGES 512
#define DQO_QPL_DEFAULT_RX_PAGES 2048

/* Maximum TSO size supported on DQO */
#define GVE_DQO_TX_MAX 0x3FFFF

Expand Down Expand Up @@ -603,11 +604,6 @@ struct gve_qpl_config {
unsigned long *qpl_id_map; /* bitmap of used qpl ids */
};

struct gve_options_dqo_rda {
u16 tx_comp_ring_entries; /* number of tx_comp descriptors */
u16 rx_buff_ring_entries; /* number of rx_buff descriptors */
};

struct gve_irq_db {
__be32 index;
} ____cacheline_aligned;
Expand All @@ -621,6 +617,56 @@ struct gve_ptype_lut {
struct gve_ptype ptypes[GVE_NUM_PTYPES];
};

/* Parameters for allocating queue page lists */
struct gve_qpls_alloc_cfg {
struct gve_qpl_config *qpl_cfg;
struct gve_queue_config *tx_cfg;
struct gve_queue_config *rx_cfg;

bool raw_addressing;
bool is_gqi;

/* Allocated resources are returned here */
struct gve_queue_page_list *qpls;
};

/* Parameters for allocating resources for tx queues */
struct gve_tx_alloc_rings_cfg {
struct gve_queue_config *qcfg;

/* qpls and qpl_cfg must already be allocated */
struct gve_queue_page_list *qpls;
struct gve_qpl_config *qpl_cfg;

u16 ring_size;
u16 start_idx;
u16 num_rings;
u16 pages_per_qpl;
bool raw_addressing;

/* Allocated resources are returned here */
struct gve_tx_ring *tx;
};

/* Parameters for allocating resources for rx queues */
struct gve_rx_alloc_rings_cfg {
/* tx config is also needed to determine QPL ids */
struct gve_queue_config *qcfg;
struct gve_queue_config *qcfg_tx;

/* qpls and qpl_cfg must already be allocated */
struct gve_queue_page_list *qpls;
struct gve_qpl_config *qpl_cfg;

u16 ring_size;
u16 pages_per_qpl;
bool raw_addressing;
bool enable_header_split;

/* Allocated resources are returned here */
struct gve_rx_ring *rx;
};

/* GVE_QUEUE_FORMAT_UNSPECIFIED must be zero since 0 is the default value
* when the entire configure_device_resources command is zeroed out and the
* queue_format is not specified.
Expand Down Expand Up @@ -650,9 +696,14 @@ struct gve_priv {
u16 num_event_counters;
u16 tx_desc_cnt; /* num desc per ring */
u16 rx_desc_cnt; /* num desc per ring */
u16 max_tx_desc_cnt;
u16 max_rx_desc_cnt;
u16 min_tx_desc_cnt;
u16 min_rx_desc_cnt;
bool modify_ring_size_enabled;
bool default_min_ring_size;
u16 tx_pages_per_qpl; /* Suggested number of pages per qpl for TX queues by NIC */
u16 rx_pages_per_qpl; /* Suggested number of pages per qpl for RX queues by NIC */
u16 rx_data_slot_cnt; /* rx buffer length */
u16 rx_pages_per_qpl; /* Number of pages per qpl for RX queues */
u64 max_registered_pages;
u64 num_registered_pages; /* num pages registered with NIC */
struct bpf_prog *xdp_prog; /* XDP BPF program */
Expand Down Expand Up @@ -724,7 +775,6 @@ struct gve_priv {
u64 link_speed;
bool up_before_suspend; /* True if dev was up before suspend */

struct gve_options_dqo_rda options_dqo_rda;
struct gve_ptype_lut *ptype_lut_dqo;

/* Must be a power of two. */
Expand Down Expand Up @@ -916,14 +966,14 @@ static inline bool gve_is_qpl(struct gve_priv *priv)
priv->queue_format == GVE_DQO_QPL_FORMAT;
}

/* Returns the number of tx queue page lists
*/
static inline u32 gve_num_tx_qpls(struct gve_priv *priv)
/* Returns the number of tx queue page lists */
static inline u32 gve_num_tx_qpls(const struct gve_queue_config *tx_cfg,
int num_xdp_queues,
bool is_qpl)
{
if (!gve_is_qpl(priv))
if (!is_qpl)
return 0;

return priv->tx_cfg.num_queues + priv->num_xdp_queues;
return tx_cfg->num_queues + num_xdp_queues;
}

/* Returns the number of XDP tx queue page lists
Expand All @@ -936,14 +986,13 @@ static inline u32 gve_num_xdp_qpls(struct gve_priv *priv)
return priv->num_xdp_queues;
}

/* Returns the number of rx queue page lists
*/
static inline u32 gve_num_rx_qpls(struct gve_priv *priv)
/* Returns the number of rx queue page lists */
static inline u32 gve_num_rx_qpls(const struct gve_queue_config *rx_cfg,
bool is_qpl)
{
if (!gve_is_qpl(priv))
if (!is_qpl)
return 0;

return priv->rx_cfg.num_queues;
return rx_cfg->num_queues;
}

static inline u32 gve_tx_qpl_id(struct gve_priv *priv, int tx_qid)
Expand All @@ -956,59 +1005,59 @@ static inline u32 gve_rx_qpl_id(struct gve_priv *priv, int rx_qid)
return priv->tx_cfg.max_queues + rx_qid;
}

/* Returns the index into priv->qpls where a certain rx queue's QPL resides */
static inline u32 gve_get_rx_qpl_id(const struct gve_queue_config *tx_cfg, int rx_qid)
{
return tx_cfg->max_queues + rx_qid;
}

static inline u32 gve_tx_start_qpl_id(struct gve_priv *priv)
{
return gve_tx_qpl_id(priv, 0);
}

static inline u32 gve_rx_start_qpl_id(struct gve_priv *priv)
/* Returns the index into priv->qpls where the first rx queue's QPL resides */
static inline u32 gve_rx_start_qpl_id(const struct gve_queue_config *tx_cfg)
{
return gve_rx_qpl_id(priv, 0);
return gve_get_rx_qpl_id(tx_cfg, 0);
}

/* Returns a pointer to the next available tx qpl in the list of qpls
*/
/* Returns a pointer to the next available tx qpl in the list of qpls */
static inline
struct gve_queue_page_list *gve_assign_tx_qpl(struct gve_priv *priv, int tx_qid)
struct gve_queue_page_list *gve_assign_tx_qpl(struct gve_tx_alloc_rings_cfg *cfg,
int tx_qid)
{
int id = gve_tx_qpl_id(priv, tx_qid);

/* QPL already in use */
if (test_bit(id, priv->qpl_cfg.qpl_id_map))
if (test_bit(tx_qid, cfg->qpl_cfg->qpl_id_map))
return NULL;

set_bit(id, priv->qpl_cfg.qpl_id_map);
return &priv->qpls[id];
set_bit(tx_qid, cfg->qpl_cfg->qpl_id_map);
return &cfg->qpls[tx_qid];
}

/* Returns a pointer to the next available rx qpl in the list of qpls
*/
/* Returns a pointer to the next available rx qpl in the list of qpls */
static inline
struct gve_queue_page_list *gve_assign_rx_qpl(struct gve_priv *priv, int rx_qid)
struct gve_queue_page_list *gve_assign_rx_qpl(struct gve_rx_alloc_rings_cfg *cfg,
int rx_qid)
{
int id = gve_rx_qpl_id(priv, rx_qid);

int id = gve_get_rx_qpl_id(cfg->qcfg_tx, rx_qid);
/* QPL already in use */
if (test_bit(id, priv->qpl_cfg.qpl_id_map))
if (test_bit(id, cfg->qpl_cfg->qpl_id_map))
return NULL;

set_bit(id, priv->qpl_cfg.qpl_id_map);
return &priv->qpls[id];
set_bit(id, cfg->qpl_cfg->qpl_id_map);
return &cfg->qpls[id];
}

/* Unassigns the qpl with the given id
*/
static inline void gve_unassign_qpl(struct gve_priv *priv, int id)
/* Unassigns the qpl with the given id */
static inline void gve_unassign_qpl(struct gve_qpl_config *qpl_cfg, int id)
{
clear_bit(id, priv->qpl_cfg.qpl_id_map);
clear_bit(id, qpl_cfg->qpl_id_map);
}

/* Returns the correct dma direction for tx and rx qpls
*/
/* Returns the correct dma direction for tx and rx qpls */
static inline enum dma_data_direction gve_qpl_dma_dir(struct gve_priv *priv,
int id)
{
if (id < gve_rx_start_qpl_id(priv))
if (id < gve_rx_start_qpl_id(&priv->tx_cfg))
return DMA_TO_DEVICE;
else
return DMA_FROM_DEVICE;
Expand All @@ -1035,6 +1084,9 @@ static inline u32 gve_xdp_tx_start_queue_id(struct gve_priv *priv)
return gve_xdp_tx_queue_id(priv, 0);
}

/* gqi napi handler defined in gve_main.c */
int gve_napi_poll(struct napi_struct *napi, int budget);

/* buffers */
int gve_alloc_page(struct gve_priv *priv, struct device *dev,
struct page **page, dma_addr_t *dma,
Expand All @@ -1051,20 +1103,36 @@ void gve_xdp_tx_flush(struct gve_priv *priv, u32 xdp_qid);
bool gve_tx_poll(struct gve_notify_block *block, int budget);
bool gve_xdp_poll(struct gve_notify_block *block, int budget);
int gve_xsk_tx_poll(struct gve_notify_block *block, int budget);
int gve_tx_alloc_rings(struct gve_priv *priv, int start_id, int num_rings);
void gve_tx_free_rings_gqi(struct gve_priv *priv, int start_id, int num_rings);
int gve_tx_alloc_rings_gqi(struct gve_priv *priv,
struct gve_tx_alloc_rings_cfg *cfg);
void gve_tx_free_rings_gqi(struct gve_priv *priv,
struct gve_tx_alloc_rings_cfg *cfg);
void gve_tx_start_ring_gqi(struct gve_priv *priv, int idx);
void gve_tx_stop_ring_gqi(struct gve_priv *priv, int idx);
u32 gve_tx_load_event_counter(struct gve_priv *priv,
struct gve_tx_ring *tx);
bool gve_tx_clean_pending(struct gve_priv *priv, struct gve_tx_ring *tx);
/* rx handling */
void gve_rx_write_doorbell(struct gve_priv *priv, struct gve_rx_ring *rx);
int gve_rx_poll(struct gve_notify_block *block, int budget);
bool gve_rx_work_pending(struct gve_rx_ring *rx);
int gve_rx_alloc_rings(struct gve_priv *priv);
void gve_rx_free_rings_gqi(struct gve_priv *priv);
int gve_rx_alloc_rings_gqi(struct gve_priv *priv,
struct gve_rx_alloc_rings_cfg *cfg);
void gve_rx_free_rings_gqi(struct gve_priv *priv,
struct gve_rx_alloc_rings_cfg *cfg);
void gve_rx_start_ring_gqi(struct gve_priv *priv, int idx);
void gve_rx_stop_ring_gqi(struct gve_priv *priv, int idx);
/* Reset */
void gve_schedule_reset(struct gve_priv *priv);
int gve_reset(struct gve_priv *priv, bool attempt_teardown);
void gve_get_curr_alloc_cfgs(struct gve_priv *priv,
struct gve_qpls_alloc_cfg *qpls_alloc_cfg,
struct gve_tx_alloc_rings_cfg *tx_alloc_cfg,
struct gve_rx_alloc_rings_cfg *rx_alloc_cfg);
int gve_adjust_config(struct gve_priv *priv,
struct gve_qpls_alloc_cfg *qpls_alloc_cfg,
struct gve_tx_alloc_rings_cfg *tx_alloc_cfg,
struct gve_rx_alloc_rings_cfg *rx_alloc_cfg);
int gve_adjust_queues(struct gve_priv *priv,
struct gve_queue_config new_rx_config,
struct gve_queue_config new_tx_config);
Expand Down
Loading
Loading