From: Waldemar Kozaczuk <[email protected]> Committer: WALDEMAR KOZACZUK <[email protected]> Branch: master
ena: adapt driver admin/setup header to OSv This patch adapts the admin/setup header ena.h to OSv. In particular it addresses following: - import atomic bitset support from FreeBSD tree (see https://github.com/freebsd/freebsd-src/blob/main/sys/sys/_bitset.h) - remove unnecessary fields from ena_adapter struct - replace the IRQ related fields with OSv equivalent (see ena_irq) - replace cleanup_task and cleanup_tq in ena_qeu struct with OSv equivalent cleanup_thread - replace enqueue_task and enqueue_tq in ena_ring struct with OSv equivalent enqueue_thread - remove RSS and DEV_NETMAP artifacts - for now define counter_* macros to disable related functionality - replace callout_reset_sbt() with equivalent callout_reset() Signed-off-by: Waldemar Kozaczuk <[email protected]> --- diff --git a/bsd/sys/dev/ena/ena.h b/bsd/sys/dev/ena/ena.h --- a/bsd/sys/dev/ena/ena.h +++ b/bsd/sys/dev/ena/ena.h @@ -38,12 +38,19 @@ #include "ena_com/ena_com.h" #include "ena_com/ena_eth_com.h" +#include <bsd/porting/callout.h> +#include <osv/msi.hh> +#include "drivers/pci-device.hh" + #define ENA_DRV_MODULE_VER_MAJOR 2 #define ENA_DRV_MODULE_VER_MINOR 6 #define ENA_DRV_MODULE_VER_SUBMINOR 3 #define ENA_DRV_MODULE_NAME "ena" +#define __STRING(x) #x /* stringify without expanding x */ +#define __XSTRING(x) __STRING(x) /* expand x, then stringify */ + #ifndef ENA_DRV_MODULE_VERSION #define ENA_DRV_MODULE_VERSION \ __XSTRING(ENA_DRV_MODULE_VER_MAJOR) "." \ @@ -135,10 +142,12 @@ * ENA device should send keep alive msg every 1 sec. * We wait for 6 sec just to be on the safe side. */ -#define ENA_DEFAULT_KEEP_ALIVE_TO (SBT_1S * 6) +#define NANOSECONDS_IN_SEC 1000000000l +#define NANOSECONDS_IN_MSEC 1000000l +#define ENA_DEFAULT_KEEP_ALIVE_TO (6 * NANOSECONDS_IN_SEC) /* Time in jiffies before concluding the transmitter is hung. */ -#define ENA_DEFAULT_TX_CMP_TO (SBT_1S * 5) +#define ENA_DEFAULT_TX_CMP_TO (5 * NANOSECONDS_IN_SEC) /* Number of queues to check for missing queues per timer tick */ #define ENA_DEFAULT_TX_MONITORED_QUEUES (4) @@ -156,6 +165,45 @@ #define PCI_DEV_ID_ENA_VF 0xec20 #define PCI_DEV_ID_ENA_VF_RSERV0 0xec21 +//These macros are taken verbatim from FreeBSD code and implement atomic bitset +#define _BITSET_BITS (sizeof(long) * 8) + +#define __howmany(x, y) (((x) + ((y) - 1)) / (y)) + +#define __bitset_words(_s) (__howmany(_s, _BITSET_BITS)) + +#define __constexpr_cond(expr) (__builtin_constant_p((expr)) && (expr)) + +#define __bitset_mask(_s, n) \ + (1UL << (__constexpr_cond(__bitset_words((_s)) == 1) ? \ + (size_t)(n) : ((n) % _BITSET_BITS))) + +#define __bitset_word(_s, n) \ + (__constexpr_cond(__bitset_words((_s)) == 1) ? \ + 0 : ((n) / _BITSET_BITS)) + +#define BITSET_DEFINE(_t, _s) \ +struct _t { \ + long __bits[__bitset_words((_s))]; \ +} + +#define BIT_ZERO(_s, p) do { \ + size_t __i; \ + for (__i = 0; __i < __bitset_words((_s)); __i++) \ + (p)->__bits[__i] = 0L; \ +} while (0) + +#define BIT_ISSET(_s, n, p) \ + ((((p)->__bits[__bitset_word(_s, n)] & __bitset_mask((_s), (n))) != 0)) + +#define BIT_SET_ATOMIC(_s, n, p) \ + atomic_set_long((volatile u_long*)(&(p)->__bits[__bitset_word(_s, n)]), \ + __bitset_mask((_s), n)) + +#define BIT_CLR_ATOMIC(_s, n, p) \ + atomic_clear_long((volatile u_long*)(&(p)->__bits[__bitset_word(_s, n)]),\ + __bitset_mask((_s), n)) + /* * Flags indicating current ENA driver state */ @@ -174,9 +222,9 @@ enum ena_flags_t { BITSET_DEFINE(_ena_state, ENA_FLAGS_NUMBER); typedef struct _ena_state ena_state_t; -#define ENA_FLAG_ZERO(adapter) \ +#define ENA_FLAG_ZERO(adapter) \ BIT_ZERO(ENA_FLAGS_NUMBER, &(adapter)->flags) -#define ENA_FLAG_ISSET(bit, adapter) \ +#define ENA_FLAG_ISSET(bit, adapter) \ BIT_ISSET(ENA_FLAGS_NUMBER, (bit), &(adapter)->flags) #define ENA_FLAG_SET_ATOMIC(bit, adapter) \ BIT_SET_ATOMIC(ENA_FLAGS_NUMBER, (bit), &(adapter)->flags) @@ -196,39 +244,30 @@ typedef struct _ena_vendor_info_t { struct ena_irq { /* Interrupt resources */ - struct resource *res; - driver_filter_t *handler; void *data; - void *cookie; unsigned int vector; - bool requested; -#ifdef RSS - int cpu; -#endif - char name[ENA_IRQNAME_SIZE]; + msix_vector *mvector; }; struct ena_que { struct ena_adapter *adapter; struct ena_ring *tx_ring; struct ena_ring *rx_ring; - struct task cleanup_task; - struct taskqueue *cleanup_tq; + sched::thread* cleanup_thread; + std::atomic<uint16_t> cleanup_pending = {0}; + std::atomic<bool> cleanup_stop = {false}; uint32_t id; -#ifdef RSS - int cpu; - cpuset_t cpu_mask; -#endif int domain; struct sysctl_oid *oid; + }; struct ena_calc_queue_size_ctx { struct ena_com_dev_get_features_ctx *get_feat_ctx; struct ena_com_dev *ena_dev; - device_t pdev; + pci::device *pdev; uint32_t tx_queue_size; uint32_t rx_queue_size; uint32_t max_tx_queue_size; @@ -237,14 +276,6 @@ struct ena_calc_queue_size_ctx { uint16_t max_rx_sgl_size; }; -#ifdef DEV_NETMAP -struct ena_netmap_tx_info { - uint32_t socket_buf_idx[ENA_PKT_MAX_BUFS]; - bus_dmamap_t map_seg[ENA_PKT_MAX_BUFS]; - unsigned int sockets_used; -}; -#endif - struct ena_tx_buffer { struct mbuf *mbuf; /* # of ena desc for this specific mbuf @@ -253,33 +284,34 @@ struct ena_tx_buffer { /* # of buffers used by this mbuf */ unsigned int num_of_bufs; - bus_dmamap_t dmamap; - /* Used to detect missing tx packets */ - struct bintime timestamp; + u64 timestamp; bool print_once; -#ifdef DEV_NETMAP - struct ena_netmap_tx_info nm_info; -#endif /* DEV_NETMAP */ - struct ena_com_buf bufs[ENA_PKT_MAX_BUFS]; } __aligned(CACHE_LINE_SIZE); struct ena_rx_buffer { struct mbuf *mbuf; - bus_dmamap_t map; struct ena_com_buf ena_buf; -#ifdef DEV_NETMAP - uint32_t netmap_buf_idx; -#endif /* DEV_NETMAP */ } __aligned(CACHE_LINE_SIZE); +//TODO: See if we need atomics or possibly these get updated/read without a need +//for locking +//In FreeBSD they seem to be atomics per CPU - see https://github.com/freebsd/freebsd-src/blob/main/sys/arm64/include/counter.h#L82 +//For now disable all the counter related code -> it seems to be used only to track +//stats +typedef u64 counter_u64_t; +#define counter_u64_zero(cnt) do {} while (0) +#define counter_u64_add(cnt,inc) do {} while (0) +#define counter_u64_add_protected(cnt,inc) do {} while (0) +#define counter_enter() do {} while (0) +#define counter_exit() do {} while (0) + struct ena_stats_tx { counter_u64_t cnt; counter_u64_t bytes; counter_u64_t prepare_ctx_err; - counter_u64_t dma_mapping_err; counter_u64_t doorbells; counter_u64_t missing_tx_comp; counter_u64_t bad_req_id; @@ -298,7 +330,6 @@ struct ena_stats_rx { counter_u64_t csum_bad; counter_u64_t mjum_alloc_fail; counter_u64_t mbuf_alloc_fail; - counter_u64_t dma_mapping_err; counter_u64_t bad_desc_num; counter_u64_t bad_req_id; counter_u64_t empty_rx_ring; @@ -328,7 +359,7 @@ struct ena_ring { }; - uint8_t first_interrupt; + std::atomic<uint8_t> first_interrupt; uint16_t no_interrupt_event_cnt; struct ena_com_rx_buf_info ena_bufs[ENA_PKT_MAX_BUFS]; @@ -351,10 +382,9 @@ struct ena_ring { struct mtx ring_mtx; char mtx_name[16]; - struct { - struct task enqueue_task; - struct taskqueue *enqueue_tq; - }; + sched::thread* enqueue_thread; + std::atomic<uint16_t> enqueue_pending = {0}; + std::atomic<bool> enqueue_stop = {false}; union { struct ena_stats_tx tx_stats; @@ -374,10 +404,6 @@ struct ena_ring { uint8_t *push_buf_intermediate_buf; int tx_last_cleanup_ticks; - -#ifdef DEV_NETMAP - bool initialized; -#endif /* DEV_NETMAP */ } __aligned(CACHE_LINE_SIZE); struct ena_stats_dev { @@ -398,30 +424,23 @@ struct ena_hw_stats { counter_u64_t tx_drops; }; +typedef struct ifnet* if_t; + /* Board specific private data structure */ struct ena_adapter { struct ena_com_dev *ena_dev; /* OS defined structs */ if_t ifp; - device_t pdev; + pci::device *pdev; struct ifmedia media; /* OS resources */ - struct resource *memory; - struct resource *registers; - struct resource *msix; - int msix_rid; + pci::bar *registers; /* MSI-X */ - struct msix_entry *msix_entries; int msix_vecs; - /* DMA tags used throughout the driver adapter for Tx and Rx */ - bus_dma_tag_t tx_buf_tag; - bus_dma_tag_t rx_buf_tag; - int dma_width; - uint32_t max_mtu; uint32_t num_io_queues; @@ -465,26 +484,20 @@ struct ena_adapter { /* Timer service */ struct callout timer_service; - sbintime_t keep_alive_timestamp; + std::atomic<u64> keep_alive_timestamp; uint32_t next_monitored_tx_qid; struct task reset_task; struct taskqueue *reset_tq; - struct task metrics_task; - struct taskqueue *metrics_tq; int wd_active; - sbintime_t keep_alive_timeout; - sbintime_t missing_tx_timeout; + u64 keep_alive_timeout; + u64 missing_tx_timeout; uint32_t missing_tx_max_queues; uint32_t missing_tx_threshold; bool disable_meta_caching; - uint16_t eni_metrics_sample_interval; - uint16_t eni_metrics_sample_interval_cnt; - /* Statistics */ struct ena_stats_dev dev_stats; struct ena_hw_stats hw_stats; - struct ena_admin_eni_stats eni_metrics; enum ena_regs_reset_reason_types reset_reason; }; @@ -499,16 +512,16 @@ struct ena_adapter { sx_init(&ena_global_lock, "ENA global lock") #define ENA_LOCK_DESTROY() sx_destroy(&ena_global_lock) #define ENA_LOCK_LOCK() sx_xlock(&ena_global_lock) -#define ENA_LOCK_UNLOCK() sx_unlock(&ena_global_lock) +#define ENA_LOCK_UNLOCK() sx_xunlock(&ena_global_lock) #define ENA_LOCK_ASSERT() sx_assert(&ena_global_lock, SA_XLOCKED) #define ENA_TIMER_INIT(_adapter) \ callout_init(&(_adapter)->timer_service, true) #define ENA_TIMER_DRAIN(_adapter) \ callout_drain(&(_adapter)->timer_service) #define ENA_TIMER_RESET(_adapter) \ - callout_reset_sbt(&(_adapter)->timer_service, SBT_1S, SBT_1S, \ - ena_timer_service, (void*)(_adapter), 0) + callout_reset(&(_adapter)->timer_service, ns2ticks(NANOSECONDS_IN_SEC), \ + ena_timer_service, (void*)(_adapter)) #define clamp_t(type, _x, min, max) min_t(type, max_t(type, _x, min), max) #define clamp_val(val, lo, hi) clamp_t(__typeof(val), val, lo, hi) @@ -531,7 +544,7 @@ ena_mbuf_count(struct mbuf *mbuf) { int count = 1; - while ((mbuf = mbuf->m_next) != NULL) + while ((mbuf = mbuf->m_hdr.mh_next) != NULL) ++count; return count; -- You received this message because you are subscribed to the Google Groups "OSv Development" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To view this discussion on the web visit https://groups.google.com/d/msgid/osv-dev/0000000000000433dc060eaf1567%40google.com.
