aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/gve/gve.h
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/gve/gve.h')
-rw-r--r--sys/dev/gve/gve.h73
1 files changed, 66 insertions, 7 deletions
diff --git a/sys/dev/gve/gve.h b/sys/dev/gve/gve.h
index 39965c8669cf..48e9a371df21 100644
--- a/sys/dev/gve/gve.h
+++ b/sys/dev/gve/gve.h
@@ -47,6 +47,21 @@
#define GVE_TX_MAX_DESCS 4
#define GVE_TX_BUFRING_ENTRIES 4096
+#define GVE_TX_TIMEOUT_PKT_SEC 5
+#define GVE_TX_TIMEOUT_CHECK_CADENCE_SEC 5
+/*
+ * If the driver finds timed out packets on a tx queue it first kicks it and
+ * records the time. If the driver again finds a timeout on the same queue
+ * before the end of the cooldown period, only then will it reset. Thus, for a
+ * reset to be able to occur at all, the cooldown must be at least as long
+ * as the tx timeout checking cadence multiplied by the number of queues.
+ */
+#define GVE_TX_TIMEOUT_MAX_TX_QUEUES 16
+#define GVE_TX_TIMEOUT_KICK_COOLDOWN_SEC \
+ (2 * GVE_TX_TIMEOUT_CHECK_CADENCE_SEC * GVE_TX_TIMEOUT_MAX_TX_QUEUES)
+
+#define GVE_TIMESTAMP_INVALID -1
+
#define ADMINQ_SIZE PAGE_SIZE
#define GVE_DEFAULT_RX_BUFFER_SIZE 2048
@@ -63,6 +78,10 @@
*/
#define GVE_QPL_DIVISOR 16
+/* Ring Size Limits */
+#define GVE_DEFAULT_MIN_RX_RING_SIZE 512
+#define GVE_DEFAULT_MIN_TX_RING_SIZE 256
+
static MALLOC_DEFINE(M_GVE, "gve", "gve allocations");
struct gve_dma_handle {
@@ -333,6 +352,14 @@ struct gve_tx_fifo {
struct gve_tx_buffer_state {
struct mbuf *mbuf;
+
+ /*
+ * Time at which the xmit tq places descriptors for mbuf's payload on a
+ * tx queue. This timestamp is invalidated when the mbuf is freed and
+ * must be checked for validity when read.
+ */
+ int64_t enqueue_time_sec;
+
struct gve_tx_iovec iov[GVE_TX_MAX_DESCS];
};
@@ -353,12 +380,21 @@ struct gve_txq_stats {
counter_u64_t tx_mbuf_defrag_err;
counter_u64_t tx_mbuf_dmamap_enomem_err;
counter_u64_t tx_mbuf_dmamap_err;
+ counter_u64_t tx_timeout;
};
#define NUM_TX_STATS (sizeof(struct gve_txq_stats) / sizeof(counter_u64_t))
struct gve_tx_pending_pkt_dqo {
struct mbuf *mbuf;
+
+ /*
+ * Time at which the xmit tq places descriptors for mbuf's payload on a
+ * tx queue. This timestamp is invalidated when the mbuf is freed and
+ * must be checked for validity when read.
+ */
+ int64_t enqueue_time_sec;
+
union {
/* RDA */
bus_dmamap_t dmamap;
@@ -392,6 +428,8 @@ struct gve_tx_ring {
uint32_t req; /* free-running total number of packets written to the nic */
uint32_t done; /* free-running total number of completed packets */
+ int64_t last_kicked; /* always-valid timestamp in seconds for the last queue kick */
+
union {
/* GQI specific stuff */
struct {
@@ -529,12 +567,17 @@ struct gve_priv {
uint16_t num_event_counters;
uint16_t default_num_queues;
uint16_t tx_desc_cnt;
+ uint16_t max_tx_desc_cnt;
+ uint16_t min_tx_desc_cnt;
uint16_t rx_desc_cnt;
+ uint16_t max_rx_desc_cnt;
+ uint16_t min_rx_desc_cnt;
uint16_t rx_pages_per_qpl;
uint64_t max_registered_pages;
uint64_t num_registered_pages;
uint32_t supported_features;
uint16_t max_mtu;
+ bool modify_ringsize_enabled;
struct gve_dma_handle counter_array_mem;
__be32 *counters;
@@ -542,7 +585,6 @@ struct gve_priv {
struct gve_irq_db *irq_db_indices;
enum gve_queue_format queue_format;
- struct gve_queue_page_list *qpls;
struct gve_queue_config tx_cfg;
struct gve_queue_config rx_cfg;
uint32_t num_queues;
@@ -586,6 +628,11 @@ struct gve_priv {
struct gve_state_flags state_flags;
struct sx gve_iface_lock;
+
+ struct callout tx_timeout_service;
+ /* The index of tx queue that the timer service will check on its next invocation */
+ uint16_t check_tx_queue_idx;
+
};
static inline bool
@@ -621,6 +668,9 @@ gve_is_qpl(struct gve_priv *priv)
/* Defined in gve_main.c */
void gve_schedule_reset(struct gve_priv *priv);
+int gve_adjust_tx_queues(struct gve_priv *priv, uint16_t new_queue_cnt);
+int gve_adjust_rx_queues(struct gve_priv *priv, uint16_t new_queue_cnt);
+int gve_adjust_ring_sizes(struct gve_priv *priv, uint16_t new_desc_cnt, bool is_rx);
/* Register access functions defined in gve_utils.c */
uint32_t gve_reg_bar_read_4(struct gve_priv *priv, bus_size_t offset);
@@ -629,17 +679,19 @@ void gve_db_bar_write_4(struct gve_priv *priv, bus_size_t offset, uint32_t val);
void gve_db_bar_dqo_write_4(struct gve_priv *priv, bus_size_t offset, uint32_t val);
/* QPL (Queue Page List) functions defined in gve_qpl.c */
-int gve_alloc_qpls(struct gve_priv *priv);
-void gve_free_qpls(struct gve_priv *priv);
+struct gve_queue_page_list *gve_alloc_qpl(struct gve_priv *priv, uint32_t id,
+ int npages, bool single_kva);
+void gve_free_qpl(struct gve_priv *priv, struct gve_queue_page_list *qpl);
int gve_register_qpls(struct gve_priv *priv);
int gve_unregister_qpls(struct gve_priv *priv);
void gve_mextadd_free(struct mbuf *mbuf);
/* TX functions defined in gve_tx.c */
-int gve_alloc_tx_rings(struct gve_priv *priv);
-void gve_free_tx_rings(struct gve_priv *priv);
+int gve_alloc_tx_rings(struct gve_priv *priv, uint16_t start_idx, uint16_t stop_idx);
+void gve_free_tx_rings(struct gve_priv *priv, uint16_t start_idx, uint16_t stop_idx);
int gve_create_tx_rings(struct gve_priv *priv);
int gve_destroy_tx_rings(struct gve_priv *priv);
+int gve_check_tx_timeout_gqi(struct gve_priv *priv, struct gve_tx_ring *tx);
int gve_tx_intr(void *arg);
int gve_xmit_ifp(if_t ifp, struct mbuf *mbuf);
void gve_qflush(if_t ifp);
@@ -650,14 +702,15 @@ void gve_tx_cleanup_tq(void *arg, int pending);
int gve_tx_alloc_ring_dqo(struct gve_priv *priv, int i);
void gve_tx_free_ring_dqo(struct gve_priv *priv, int i);
void gve_clear_tx_ring_dqo(struct gve_priv *priv, int i);
+int gve_check_tx_timeout_dqo(struct gve_priv *priv, struct gve_tx_ring *tx);
int gve_tx_intr_dqo(void *arg);
int gve_xmit_dqo(struct gve_tx_ring *tx, struct mbuf **mbuf_ptr);
int gve_xmit_dqo_qpl(struct gve_tx_ring *tx, struct mbuf *mbuf);
void gve_tx_cleanup_tq_dqo(void *arg, int pending);
/* RX functions defined in gve_rx.c */
-int gve_alloc_rx_rings(struct gve_priv *priv);
-void gve_free_rx_rings(struct gve_priv *priv);
+int gve_alloc_rx_rings(struct gve_priv *priv, uint16_t start_idx, uint16_t stop_idx);
+void gve_free_rx_rings(struct gve_priv *priv, uint16_t start_idx, uint16_t stop_idx);
int gve_create_rx_rings(struct gve_priv *priv);
int gve_destroy_rx_rings(struct gve_priv *priv);
int gve_rx_intr(void *arg);
@@ -685,6 +738,12 @@ int gve_alloc_irqs(struct gve_priv *priv);
void gve_unmask_all_queue_irqs(struct gve_priv *priv);
void gve_mask_all_queue_irqs(struct gve_priv *priv);
+/* Miscellaneous functions defined in gve_utils.c */
+void gve_invalidate_timestamp(int64_t *timestamp_sec);
+int64_t gve_seconds_since(int64_t *timestamp_sec);
+void gve_set_timestamp(int64_t *timestamp_sec);
+bool gve_timestamp_valid(int64_t *timestamp_sec);
+
/* Systcl functions defined in gve_sysctl.c */
extern bool gve_disable_hw_lro;
extern char gve_queue_format[8];