patches/header_split_ethool_flag.cocci (274 lines of code) (raw):
@ ethtool_netlink @
@@
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6,8,0))
#include <linux/ethtool_netlink.h>
+#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(6,8,0) */
+#include <linux/ethtool.h>
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(6,8,0) */
@ gve_get_ringparam @
@@
gve_get_ringparam(...)
{
...
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6,8,0))
if (!gve_header_split_supported(priv))
kernel_cmd->tcp_data_split = ETHTOOL_TCP_DATA_SPLIT_UNKNOWN;
else if (priv->header_split_enabled)
kernel_cmd->tcp_data_split = ETHTOOL_TCP_DATA_SPLIT_ENABLED;
else
kernel_cmd->tcp_data_split = ETHTOOL_TCP_DATA_SPLIT_DISABLED;
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(6,8,0) */
...
}
@ gve_set_ringparam @
@@
gve_set_ringparam(...)
{
...
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6,8,0))
int err;
err = gve_set_hsplit_config(...);
if (err)
return err;
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(6,8,0) */
...
}
@ gve_ethtool_ops @
identifier gve_ethtool_ops, ethtool_use_hsplit_flag;
@@
const struct ethtool_ops gve_ethtool_ops = {
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6,8,0))
.supported_ring_params = ethtool_use_hsplit_flag,
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(6,8,0) */
.get_drvinfo = gve_get_drvinfo,
};
@ gve_set_hsplit_config @
@@
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6,8,0))
int gve_set_hsplit_config(struct gve_priv *priv, u8 tcp_data_split)
{
...
}
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(6,8,0) */
@ gve_set_hsplit_config_declaration @
@@
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6,8,0))
int gve_set_hsplit_config(struct gve_priv *priv, u8 tcp_data_split);
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(6,8,0) */
@ add_gve_priv_variables @
@@
struct gve_priv {
...
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(6,8,0))
+u8 header_split_strict;
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(6,8,0) */
};
@ add_priv_flag_bits @
@@
enum gve_ethtool_flags_bit {
GVE_PRIV_FLAGS_REPORT_STATS = 0,
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(6,8,0))
+ GVE_PRIV_FLAGS_ENABLE_HEADER_SPLIT = 1,
+ GVE_PRIV_FLAGS_ENABLE_STRICT_HEADER_SPLIT = 2,
+ GVE_PRIV_FLAGS_ENABLE_MAX_RX_BUFFER_SIZE = 3,
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(6,8,0) */
};
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(6,8,0))
+#define GVE_PRIV_FLAGS_MASK \
+ (BIT(GVE_PRIV_FLAGS_REPORT_STATS) | \
+ BIT(GVE_PRIV_FLAGS_ENABLE_HEADER_SPLIT) | \
+ BIT(GVE_PRIV_FLAGS_ENABLE_STRICT_HEADER_SPLIT) | \
+ BIT(GVE_PRIV_FLAGS_ENABLE_MAX_RX_BUFFER_SIZE))
+
+static inline int gve_get_enable_header_split(struct gve_priv *priv)
+{
+ return test_bit(GVE_PRIV_FLAGS_ENABLE_HEADER_SPLIT, &priv->ethtool_flags);
+}
+
+static inline int gve_get_enable_max_rx_buffer_size(struct gve_priv *priv)
+{
+ return test_bit(GVE_PRIV_FLAGS_ENABLE_MAX_RX_BUFFER_SIZE, &priv->ethtool_flags);
+}
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(6,8,0) */
@ gve_get_priv_flags @
identifier gve_get_priv_flags;
@@
gve_get_priv_flags(...)
{
struct gve_priv *priv = netdev_priv(netdev);
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6,8,0))
u32 ret_flags = 0;
/* Only 1 flag exists currently: report-stats (BIT(O)), so set that flag. */
if (priv->ethtool_flags & BIT(0))
ret_flags |= BIT(0);
return ret_flags;
+#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(6,8,0) */
+ return priv->ethtool_flags & GVE_PRIV_FLAGS_MASK;
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(6,8,0) */
}
@ gve_set_priv_flags @
@@
static int gve_set_priv_flags(struct net_device *netdev, u32 flags)
{
struct gve_priv *priv = netdev_priv(netdev);
...
int num_tx_queues;
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(6,8,0))
+ u64 flag_diff;
+ int new_packet_buffer_size;
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(6,8,0) */
num_tx_queues = gve_num_tx_queues(priv);
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6,8,0))
ori_flags = READ_ONCE(priv->ethtool_flags);
new_flags = ori_flags;
/* Only one priv flag exists: report-stats (BIT(0))*/
if (flags & BIT(0))
new_flags |= BIT(0);
else
new_flags &= ~(BIT(0));
+#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(6,8,0) */
+ /* If turning off header split, strict header split will be turned off too*/
+ if (gve_get_enable_header_split(priv) &&
+ !(flags & BIT(GVE_PRIV_FLAGS_ENABLE_HEADER_SPLIT))) {
+ flags &= ~BIT(GVE_PRIV_FLAGS_ENABLE_HEADER_SPLIT);
+ flags &= ~BIT(GVE_PRIV_FLAGS_ENABLE_STRICT_HEADER_SPLIT);
+ }
+
+ /* If strict header-split is requested, turn on regular header-split */
+ if (flags & BIT(GVE_PRIV_FLAGS_ENABLE_STRICT_HEADER_SPLIT))
+ flags |= BIT(GVE_PRIV_FLAGS_ENABLE_HEADER_SPLIT);
+
+ /* Make sure header-split is available */
+ if ((flags & BIT(GVE_PRIV_FLAGS_ENABLE_HEADER_SPLIT)) &&
+ !(priv->header_buf_size)) {
+ dev_err(&priv->pdev->dev,
+ "Header-split not available\n");
+ return -EINVAL;
+ }
+
+ if ((flags & BIT(GVE_PRIV_FLAGS_ENABLE_MAX_RX_BUFFER_SIZE)) &&
+ priv->max_rx_buffer_size <= GVE_DEFAULT_RX_BUFFER_SIZE) {
+ dev_err(&priv->pdev->dev,
+ "Max-rx-buffer-size not available\n");
+ return -EINVAL;
+ }
+
+ ori_flags = READ_ONCE(priv->ethtool_flags);
+
+ new_flags = flags & GVE_PRIV_FLAGS_MASK;
+
+ flag_diff = new_flags ^ ori_flags;
+
+ if ((flag_diff & BIT(GVE_PRIV_FLAGS_ENABLE_HEADER_SPLIT)) ||
+ (flag_diff & BIT(GVE_PRIV_FLAGS_ENABLE_MAX_RX_BUFFER_SIZE))) {
+ bool enable_hdr_split =
+ new_flags & BIT(GVE_PRIV_FLAGS_ENABLE_HEADER_SPLIT);
+ bool enable_max_buffer_size =
+ new_flags & BIT(GVE_PRIV_FLAGS_ENABLE_MAX_RX_BUFFER_SIZE);
+ int err;
+
+ if (enable_max_buffer_size)
+ new_packet_buffer_size = priv->max_rx_buffer_size;
+ else
+ new_packet_buffer_size = GVE_DEFAULT_RX_BUFFER_SIZE;
+
+ err = gve_set_buffer_size_config(priv,
+ enable_hdr_split,
+ new_packet_buffer_size);
+ if (err)
+ return err;
+ }
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(6,8,0) */
priv->ethtool_flags = new_flags;
...
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(6,8,0))
+ priv->header_split_strict =
+ (priv->ethtool_flags &
+ BIT(GVE_PRIV_FLAGS_ENABLE_STRICT_HEADER_SPLIT)) ? true : false;
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(6,8,0) */
return 0;
}
@ gve_gstrings_priv_flags @
@@
const char gve_gstrings_priv_flags[][ETH_GSTRING_LEN] = {
"report-stats",
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(6,8,0))
+ "enable-header-split", "enable-strict-header-split",
+ "enable-max-rx-buffer-size"
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(6,8,0) */
};
@ gve_set_buffer_size_config @
identifier gve_tx_timeout;
@@
static void gve_tx_timeout(struct net_device *dev, unsigned int txqueue)
{
...
}
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(6,8,0))
+int gve_set_buffer_size_config(struct gve_priv *priv, bool enable_hdr_split,
+ int new_pkt_buf_size)
+{
+ struct gve_tx_alloc_rings_cfg tx_alloc_cfg = {0};
+ struct gve_rx_alloc_rings_cfg rx_alloc_cfg = {0};
+ int err = 0;
+
+ gve_get_curr_alloc_cfgs(priv, &tx_alloc_cfg, &rx_alloc_cfg);
+
+ rx_alloc_cfg.enable_header_split = enable_hdr_split;
+ rx_alloc_cfg.packet_buffer_size = new_pkt_buf_size;
+
+ if (netif_running(priv->dev)) {
+ err = gve_adjust_config(priv, &tx_alloc_cfg, &rx_alloc_cfg);
+ }
+ return err;
+}
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(6,8,0) */
@ gve_set_buffer_size_config_declaration @
@@
static inline u32 gve_xdp_tx_start_queue_id(struct gve_priv *priv)
{
...
}
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(6,8,0))
+int gve_set_buffer_size_config(struct gve_priv *priv, bool enable_hdr_split,
+ int new_pkt_buf_size);
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(6,8,0) */
@ gve_rx_dqo @
@@
int gve_rx_dqo(...)
{
...
if (unlikely(hbo
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(6,8,0))
+ && priv->header_split_strict
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(6,8,0) */
)) {
gve_enqueue_buf_state(rx, &rx->dqo.recycled_buf_states,
buf_state);
return -EFAULT;
}
...
if (sph) {
...
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(6,8,0))
+ if (!hbo) {
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(6,8,0) */
dma_sync_single_for_cpu(&priv->pdev->dev,
buf_state->hdr_buf->addr,
hdr_len, DMA_FROM_DEVICE);
rx->ctx.skb_head = gve_rx_copy_data(priv->dev, napi,
buf_state->hdr_buf->data,
hdr_len);
if (unlikely(!rx->ctx.skb_head))
goto error;
rx->ctx.skb_tail = rx->ctx.skb_head;
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(6,8,0))
+ }
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(6,8,0) */
...
}
...
}