Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
5 changes: 5 additions & 0 deletions build/gve.h
Original file line number Diff line number Diff line change
Expand Up @@ -1266,6 +1266,11 @@ static inline bool gve_supports_xdp_xmit(struct gve_priv *priv)
}
}

static inline bool gve_is_clock_enabled(struct gve_priv *priv)
{
return priv->nic_ts_report;
}

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

Expand Down
2 changes: 1 addition & 1 deletion build/gve_desc_dqo.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
#define GVE_TX_MIN_TSO_MSS_DQO 88

#ifndef __LITTLE_ENDIAN_BITFIELD
#error "Only little endian supported"
"Only little endian supported"
#endif

/* Basic TX descriptor (DTYPE 0x0C) */
Expand Down
96 changes: 65 additions & 31 deletions build/gve_ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -222,11 +222,13 @@ gve_get_ethtool_stats(struct net_device *netdev,
u64 tmp_rx_pkts, tmp_rx_hsplit_pkt, tmp_rx_bytes, tmp_rx_hsplit_bytes,
tmp_rx_skb_alloc_fail, tmp_rx_buf_alloc_fail,
tmp_rx_desc_err_dropped_pkt, tmp_rx_hsplit_unsplit_pkt,
tmp_tx_pkts, tmp_tx_bytes;
tmp_tx_pkts, tmp_tx_bytes,
tmp_xdp_tx_errors, tmp_xdp_redirect_errors;
u64 rx_buf_alloc_fail, rx_desc_err_dropped_pkt, rx_hsplit_unsplit_pkt,
rx_pkts, rx_hsplit_pkt, rx_skb_alloc_fail, rx_bytes, tx_pkts, tx_bytes,
tx_dropped;
int stats_idx, base_stats_idx, max_stats_idx;
tx_dropped, xdp_tx_errors, xdp_redirect_errors;
int rx_base_stats_idx, max_rx_stats_idx, max_tx_stats_idx;
int stats_idx, stats_region_len, nic_stats_len;
struct stats *report_stats;
int *rx_qid_to_stats_idx;
int *tx_qid_to_stats_idx;
Expand Down Expand Up @@ -271,6 +273,7 @@ gve_get_ethtool_stats(struct net_device *netdev,
for (rx_pkts = 0, rx_bytes = 0, rx_hsplit_pkt = 0,
rx_skb_alloc_fail = 0, rx_buf_alloc_fail = 0,
rx_desc_err_dropped_pkt = 0, rx_hsplit_unsplit_pkt = 0,
xdp_tx_errors = 0, xdp_redirect_errors = 0,
ring = 0;
ring < priv->rx_cfg.num_queues; ring++) {
if (priv->rx) {
Expand All @@ -288,6 +291,9 @@ gve_get_ethtool_stats(struct net_device *netdev,
rx->rx_desc_err_dropped_pkt;
tmp_rx_hsplit_unsplit_pkt =
rx->rx_hsplit_unsplit_pkt;
tmp_xdp_tx_errors = rx->xdp_tx_errors;
tmp_xdp_redirect_errors =
rx->xdp_redirect_errors;
} while (u64_stats_fetch_retry(&priv->rx[ring].statss,
start));
rx_pkts += tmp_rx_pkts;
Expand All @@ -297,6 +303,8 @@ gve_get_ethtool_stats(struct net_device *netdev,
rx_buf_alloc_fail += tmp_rx_buf_alloc_fail;
rx_desc_err_dropped_pkt += tmp_rx_desc_err_dropped_pkt;
rx_hsplit_unsplit_pkt += tmp_rx_hsplit_unsplit_pkt;
xdp_tx_errors += tmp_xdp_tx_errors;
xdp_redirect_errors += tmp_xdp_redirect_errors;
}
}
for (tx_pkts = 0, tx_bytes = 0, tx_dropped = 0, ring = 0;
Expand All @@ -322,8 +330,8 @@ gve_get_ethtool_stats(struct net_device *netdev,
data[i++] = rx_bytes;
data[i++] = tx_bytes;
/* total rx dropped packets */
data[i++] = rx_skb_alloc_fail + rx_buf_alloc_fail +
rx_desc_err_dropped_pkt;
data[i++] = rx_skb_alloc_fail + rx_desc_err_dropped_pkt +
xdp_tx_errors + xdp_redirect_errors;
data[i++] = tx_dropped;
data[i++] = priv->tx_timeo_cnt;
data[i++] = rx_skb_alloc_fail;
Expand All @@ -338,20 +346,38 @@ gve_get_ethtool_stats(struct net_device *netdev,
data[i++] = priv->stats_report_trigger_cnt;
i = GVE_MAIN_STATS_LEN;

/* For rx cross-reporting stats, start from nic rx stats in report */
base_stats_idx = GVE_TX_STATS_REPORT_NUM * num_tx_queues +
GVE_RX_STATS_REPORT_NUM * priv->rx_cfg.num_queues;
/* The boundary between driver stats and NIC stats shifts if there are
* stopped queues.
*/
base_stats_idx += NIC_RX_STATS_REPORT_NUM * num_stopped_rxqs +
NIC_TX_STATS_REPORT_NUM * num_stopped_txqs;
max_stats_idx = NIC_RX_STATS_REPORT_NUM *
(priv->rx_cfg.num_queues - num_stopped_rxqs) +
base_stats_idx;
rx_base_stats_idx = 0;
max_rx_stats_idx = 0;
max_tx_stats_idx = 0;
stats_region_len = priv->stats_report_len -
sizeof(struct gve_stats_report);
nic_stats_len = (NIC_RX_STATS_REPORT_NUM * priv->rx_cfg.num_queues +
NIC_TX_STATS_REPORT_NUM * num_tx_queues) * sizeof(struct stats);
if (unlikely((stats_region_len -
nic_stats_len) % sizeof(struct stats))) {
net_err_ratelimited("Starting index of NIC stats should be multiple of stats size");
} else {
/* For rx cross-reporting stats,
* start from nic rx stats in report
*/
rx_base_stats_idx = (stats_region_len - nic_stats_len) /
sizeof(struct stats);
/* The boundary between driver stats and NIC stats
* shifts if there are stopped queues
*/
rx_base_stats_idx += NIC_RX_STATS_REPORT_NUM *
num_stopped_rxqs + NIC_TX_STATS_REPORT_NUM *
num_stopped_txqs;
max_rx_stats_idx = NIC_RX_STATS_REPORT_NUM *
(priv->rx_cfg.num_queues - num_stopped_rxqs) +
rx_base_stats_idx;
max_tx_stats_idx = NIC_TX_STATS_REPORT_NUM *
(num_tx_queues - num_stopped_txqs) +
max_rx_stats_idx;
}
/* Preprocess the stats report for rx, map queue id to start index */
skip_nic_stats = false;
for (stats_idx = base_stats_idx; stats_idx < max_stats_idx;
for (stats_idx = rx_base_stats_idx; stats_idx < max_rx_stats_idx;
stats_idx += NIC_RX_STATS_REPORT_NUM) {
u32 stat_name = be32_to_cpu(report_stats[stats_idx].stat_name);
u32 queue_id = be32_to_cpu(report_stats[stats_idx].queue_id);
Expand Down Expand Up @@ -384,6 +410,9 @@ gve_get_ethtool_stats(struct net_device *netdev,
tmp_rx_buf_alloc_fail = rx->rx_buf_alloc_fail;
tmp_rx_desc_err_dropped_pkt =
rx->rx_desc_err_dropped_pkt;
tmp_xdp_tx_errors = rx->xdp_tx_errors;
tmp_xdp_redirect_errors =
rx->xdp_redirect_errors;
} while (u64_stats_fetch_retry(&priv->rx[ring].statss,
start));
data[i++] = tmp_rx_bytes;
Expand All @@ -394,8 +423,9 @@ gve_get_ethtool_stats(struct net_device *netdev,
data[i++] = rx->rx_frag_alloc_cnt;
/* rx dropped packets */
data[i++] = tmp_rx_skb_alloc_fail +
tmp_rx_buf_alloc_fail +
tmp_rx_desc_err_dropped_pkt;
tmp_rx_desc_err_dropped_pkt +
tmp_xdp_tx_errors +
tmp_xdp_redirect_errors;
data[i++] = rx->rx_copybreak_pkt;
data[i++] = rx->rx_copied_pkt;
/* stats from NIC */
Expand Down Expand Up @@ -427,14 +457,9 @@ gve_get_ethtool_stats(struct net_device *netdev,
i += priv->rx_cfg.num_queues * NUM_GVE_RX_CNTS;
}

/* For tx cross-reporting stats, start from nic tx stats in report */
base_stats_idx = max_stats_idx;
max_stats_idx = NIC_TX_STATS_REPORT_NUM *
(num_tx_queues - num_stopped_txqs) +
max_stats_idx;
/* Preprocess the stats report for tx, map queue id to start index */
skip_nic_stats = false;
for (stats_idx = base_stats_idx; stats_idx < max_stats_idx;
/* NIC TX stats start right after NIC RX stats */
for (stats_idx = max_rx_stats_idx; stats_idx < max_tx_stats_idx;
stats_idx += NIC_TX_STATS_REPORT_NUM) {
u32 stat_name = be32_to_cpu(report_stats[stats_idx].stat_name);
u32 queue_id = be32_to_cpu(report_stats[stats_idx].queue_id);
Expand Down Expand Up @@ -991,15 +1016,23 @@ static int gve_set_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *cmd)
return err;
}

static u32 gve_get_rx_ring_count(struct net_device *netdev)
{
struct gve_priv *priv = netdev_priv(netdev);

return priv->rx_cfg.num_queues;
}

static int gve_get_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *cmd, u32 *rule_locs)
{
struct gve_priv *priv = netdev_priv(netdev);
int err = 0;

switch (cmd->cmd) {
case ETHTOOL_GRXRINGS:
cmd->data = priv->rx_cfg.num_queues;
#if LINUX_VERSION_CODE < KERNEL_VERSION(7,0,0)
case ETHTOOL_GRXRINGS: cmd->data = gve_get_rx_ring_count(netdev);
break;
#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(7,0,0) */
case ETHTOOL_GRXCLSRLCNT:
if (!priv->max_flow_rules)
return -EOPNOTSUPP;
Expand Down Expand Up @@ -1192,9 +1225,8 @@ static int gve_get_ts_info(struct net_device *netdev
struct gve_priv *priv = netdev_priv(netdev);

ethtool_op_get_ts_info(netdev, info);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,9,0)

if (priv->nic_timestamp_supported) {
if (gve_is_clock_enabled(priv)) {
info->so_timestamping |= SOF_TIMESTAMPING_RX_HARDWARE |
SOF_TIMESTAMPING_RAW_HARDWARE;

Expand All @@ -1204,7 +1236,6 @@ static int gve_get_ts_info(struct net_device *netdev
if (priv->ptp)
info->phc_index = ptp_clock_index(priv->ptp->clock);
}
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(5,9,0) */

return 0;
}
Expand Down Expand Up @@ -1233,6 +1264,9 @@ const struct ethtool_ops gve_ethtool_ops = {
.get_channels = gve_get_channels,
.set_rxnfc = gve_set_rxnfc,
.get_rxnfc = gve_get_rxnfc,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6,19,0)
.get_rx_ring_count = gve_get_rx_ring_count,
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(6,19,0) */
.get_rxfh_indir_size = gve_get_rxfh_indir_size,
.get_rxfh_key_size = gve_get_rxfh_key_size,
.get_rxfh = gve_get_rxfh,
Expand Down
43 changes: 32 additions & 11 deletions build/gve_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
#define GVE_DEFAULT_RX_COPYBREAK (256)

#define DEFAULT_MSG_LEVEL (NETIF_MSG_DRV | NETIF_MSG_LINK)
#define GVE_VERSION "1.4.8-0--34ae86a-oot"
#define GVE_VERSION "1.4.9-0--6cc52f7-oot"
#define GVE_VERSION_PREFIX "GVE-"

// Minimum amount of time between queue kicks in msec (10 seconds)
Expand Down Expand Up @@ -336,9 +336,9 @@ static int gve_alloc_stats_report(struct gve_priv *priv)
int tx_stats_num, rx_stats_num;

tx_stats_num = (GVE_TX_STATS_REPORT_NUM + NIC_TX_STATS_REPORT_NUM) *
gve_num_tx_queues(priv);
priv->tx_cfg.max_queues;
rx_stats_num = (GVE_RX_STATS_REPORT_NUM + NIC_RX_STATS_REPORT_NUM) *
priv->rx_cfg.num_queues;
priv->rx_cfg.max_queues;
#if !defined(struct_size) || !defined(size_add)
priv->stats_report_len = sizeof(*priv->stats_report) + sizeof((priv->stats_report)->stats[0]) * (tx_stats_num + rx_stats_num);
#else
Expand Down Expand Up @@ -706,9 +706,17 @@ static int gve_alloc_notify_blocks(struct gve_priv *priv)
snprintf(block->name, sizeof(block->name), "gve-ntfy-blk%d@pci:%s",
i, pci_name(priv->pdev));
block->priv = priv;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,13,0)
err = request_irq(priv->msix_vectors[msix_idx].vector,
gve_is_gqi(priv) ? gve_intr : gve_intr_dqo,
IRQF_NO_AUTOEN, block->name, block);
#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(5,13,0) */
irq_set_status_flags(priv->msix_vectors[msix_idx].vector,
IRQ_NOAUTOEN);
err = request_irq(priv->msix_vectors[msix_idx].vector,
gve_is_gqi(priv) ? gve_intr : gve_intr_dqo,
0, block->name, block);
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(5,13,0) */
if (err) {
dev_err(&priv->pdev->dev,
"Failed to receive msix vector %d\n", i);
Expand Down Expand Up @@ -855,10 +863,12 @@ static int gve_setup_device_resources(struct gve_priv *priv)
}
}

err = gve_init_clock(priv);
if (err) {
dev_err(&priv->pdev->dev, "Failed to init clock");
goto abort_with_ptype_lut;
if (priv->nic_timestamp_supported) {
err = gve_init_clock(priv);
if (err) {
dev_warn(&priv->pdev->dev, "Failed to init clock, continuing without PTP support");
err = 0;
}
}

err = gve_init_rss_config(priv, priv->rx_cfg.num_queues);
Expand Down Expand Up @@ -2589,7 +2599,7 @@ static int gve_set_ts_config(struct net_device *dev,
}

if (kernel_config->rx_filter != HWTSTAMP_FILTER_NONE) {
if (!priv->nic_ts_report) {
if (!gve_is_clock_enabled(priv)) {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,12,0)
NL_SET_ERR_MSG_MOD(extack,
"RX timestamping is not supported");
Expand Down Expand Up @@ -3124,8 +3134,13 @@ static void gve_rx_queue_mem_free(struct net_device *dev, void *per_q_mem)
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(6,10,0)) */

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6,10,0))
static int gve_rx_queue_mem_alloc(struct net_device *dev, void *per_q_mem,
int idx)
static int gve_rx_queue_mem_alloc(struct net_device *dev
#if LINUX_VERSION_CODE >= KERNEL_VERSION(7,0,0)
,
struct netdev_queue_config *qcfg
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(7,0,0) */
,
void *per_q_mem, int idx)
{
struct gve_priv *priv = netdev_priv(dev);
struct gve_rx_alloc_rings_cfg cfg = {0};
Expand All @@ -3148,7 +3163,13 @@ static int gve_rx_queue_mem_alloc(struct net_device *dev, void *per_q_mem,
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(6,10,0)) */

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6,10,0))
static int gve_rx_queue_start(struct net_device *dev, void *per_q_mem, int idx)
static int gve_rx_queue_start(struct net_device *dev
#if LINUX_VERSION_CODE >= KERNEL_VERSION(7,0,0)
,
struct netdev_queue_config *qcfg
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(7,0,0) */
,
void *per_q_mem, int idx)
{
struct gve_priv *priv = netdev_priv(dev);
struct gve_rx_ring *gve_per_q_mem;
Expand Down
8 changes: 0 additions & 8 deletions build/gve_ptp.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,11 +84,6 @@ static int gve_ptp_init(struct gve_priv *priv)
struct gve_ptp *ptp;
int err;

if (!priv->nic_timestamp_supported) {
dev_dbg(&priv->pdev->dev, "Device does not support PTP\n");
return -EOPNOTSUPP;
}

priv->ptp = kzalloc(sizeof(*priv->ptp), GFP_KERNEL);
if (!priv->ptp)
return -ENOMEM;
Expand Down Expand Up @@ -130,9 +125,6 @@ int gve_init_clock(struct gve_priv *priv)
{
int err;

if (!priv->nic_timestamp_supported)
return 0;

err = gve_ptp_init(priv);
if (err)
return err;
Expand Down
Loading