[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [UNIKRAFT PATCH v3 3/5] lib/ukring: Adapt {ring.c, ring.h} to Unikraft
This includes Unikraft-centric headers and types. Signed-off-by: Alexander Jung <alexander.jung@xxxxxxxxx> --- lib/ukring/include/uk/ring.h | 101 +++++++++++++++++++++++-------------------- lib/ukring/ring.c | 37 ++++++++-------- 2 files changed, 72 insertions(+), 66 deletions(-) diff --git a/lib/ukring/include/uk/ring.h b/lib/ukring/include/uk/ring.h index abc95fe..6bc789d 100644 --- a/lib/ukring/include/uk/ring.h +++ b/lib/ukring/include/uk/ring.h @@ -32,12 +32,16 @@ #ifndef _SYS_BUF_RING_H_ #define _SYS_BUF_RING_H_ -#include <machine/cpu.h> +#include <errno.h> +#include <uk/mutex.h> +#include <uk/print.h> +#include <uk/config.h> +#include <uk/assert.h> +#include <uk/plat/lcpu.h> +#include <uk/arch/atomic.h> +#include <uk/essentials.h> +#include <uk/preempt.h> -#ifdef DEBUG_BUFRING -#include <sys/lock.h> -#include <sys/mutex.h> -#endif struct buf_ring { @@ -50,8 +54,8 @@ struct buf_ring { volatile uint32_t br_cons_tail; int br_cons_size; int br_cons_mask; -#ifdef DEBUG_BUFRING - struct mtx *br_lock; +#ifdef CONFIG_LIBUKRING_DEBUG_BUFRING + struct uk_mutex *br_lock; #endif void *br_ring[0] __aligned(CACHE_LINE_SIZE); }; @@ -66,7 +70,7 @@ buf_ring_enqueue(struct buf_ring *br, void *buf) { uint32_t prod_head, prod_next, cons_tail; -#ifdef DEBUG_BUFRING +#ifdef CONFIG_LIBUKRING_DEBUG_BUFRING int i; /* @@ -77,11 +81,11 @@ buf_ring_enqueue(struct buf_ring *br, void *buf) for (i = br->br_cons_head; i != br->br_prod_head; i = ((i + 1) & br->br_cons_mask)) if (br->br_ring[i] == buf) - panic("buf=%p already enqueue at %d prod=%d cons=%d", + UK_CRASH("buf=%p already enqueue at %d prod=%d cons=%d", buf, i, br->br_prod_tail, br->br_cons_tail); #endif - critical_enter(); + uk_preempt_enable(); do { prod_head = br->br_prod_head; @@ -92,16 +96,17 @@ buf_ring_enqueue(struct buf_ring *br, void *buf) rmb(); if (prod_head == br->br_prod_head && cons_tail == br->br_cons_tail) { br->br_drops++; - critical_exit(); + uk_preempt_disable(); return -ENOBUFS; } continue; } - } while (!atomic_cmpset_acq_int(&br->br_prod_head, prod_head, prod_next)); + } while (!ukarch_compare_exchange_sync(&br->br_prod_head, prod_head, + prod_next)); -#ifdef DEBUG_BUFRING +#ifdef CONFIG_LIBUKRING_DEBUG_BUFRING if (br->br_ring[prod_head] != NULL) - panic("dangling value in enqueue"); + UK_CRASH("dangling value in enqueue"); #endif br->br_ring[prod_head] = buf; @@ -112,10 +117,10 @@ buf_ring_enqueue(struct buf_ring *br, void *buf) * to complete */ while (br->br_prod_tail != prod_head) - cpu_spinwait(); + ukarch_spinwait(); - atomic_store_rel_int(&br->br_prod_tail, prod_next); - critical_exit(); + ukarch_store_n(&br->br_prod_tail, prod_next); + uk_preempt_disable(); return 0; } @@ -130,21 +135,22 @@ buf_ring_dequeue_mc(struct buf_ring *br) uint32_t cons_head, cons_next; void *buf; - critical_enter(); + uk_preempt_enable(); do { cons_head = br->br_cons_head; cons_next = (cons_head + 1) & br->br_cons_mask; if (cons_head == br->br_prod_tail) { - critical_exit(); + uk_preempt_disable(); return NULL; } - } while (!atomic_cmpset_acq_int(&br->br_cons_head, cons_head, cons_next)); + } while (!ukarch_compare_exchange_sync(&br->br_cons_head, cons_head, + cons_next)); buf = br->br_ring[cons_head]; -#ifdef DEBUG_BUFRING +#ifdef CONFIG_LIBUKRING_DEBUG_BUFRING br->br_ring[cons_head] = NULL; #endif @@ -154,10 +160,10 @@ buf_ring_dequeue_mc(struct buf_ring *br) * to complete */ while (br->br_cons_tail != cons_head) - cpu_spinwait(); + ukarch_spinwait(); - atomic_store_rel_int(&br->br_cons_tail, cons_next); - critical_exit(); + ukarch_store_n(&br->br_cons_tail, cons_next); + uk_preempt_disable(); return buf; } @@ -201,12 +207,12 @@ buf_ring_dequeue_sc(struct buf_ring *br) * * <1> Load (on core 1) from br->br_ring[cons_head] can be reordered (speculative readed) by CPU. */ -#if defined(__arm__) || defined(__aarch64__) - cons_head = atomic_load_acq_32(&br->br_cons_head); +#if defined(CONFIG_ARCH_ARM_32) || defined(CONFIG_ARCH_ARM_64) + cons_head = ukarch_load_n(&br->br_cons_head); #else cons_head = br->br_cons_head; #endif - prod_tail = atomic_load_acq_32(&br->br_prod_tail); + prod_tail = ukarch_load_n(&br->br_prod_tail); cons_next = (cons_head + 1) & br->br_cons_mask; #ifdef PREFETCH_DEFINED @@ -227,14 +233,14 @@ buf_ring_dequeue_sc(struct buf_ring *br) br->br_cons_head = cons_next; buf = br->br_ring[cons_head]; -#ifdef DEBUG_BUFRING +#ifdef CONFIG_LIBUKRING_DEBUG_BUFRING br->br_ring[cons_head] = NULL; - if (!mtx_owned(br->br_lock)) - panic("lock not held on single consumer dequeue"); + if (!uk_mutex_is_locked(br->br_lock)) + UK_CRASH("lock not held on single consumer dequeue: %d", br->br_lock->lock_count); if (br->br_cons_tail != cons_head) - panic("inconsistent list cons_tail=%d cons_head=%d", + UK_CRASH("inconsistent list cons_tail=%d cons_head=%d", br->br_cons_tail, cons_head); #endif @@ -262,7 +268,7 @@ buf_ring_advance_sc(struct buf_ring *br) br->br_cons_head = cons_next; -#ifdef DEBUG_BUFRING +#ifdef CONFIG_LIBUKRING_DEBUG_BUFRING br->br_ring[cons_head] = NULL; #endif @@ -288,8 +294,8 @@ buf_ring_advance_sc(struct buf_ring *br) static __inline void buf_ring_putback_sc(struct buf_ring *br, void *new) { - KASSERT(br->br_cons_head != br->br_prod_tail, - ("Buf-Ring has none in putback")); + /* Buffer ring has none in putback */ + UK_ASSERT(br->br_cons_head != br->br_prod_tail); br->br_ring[br->br_cons_head] = new; } @@ -301,9 +307,9 @@ buf_ring_putback_sc(struct buf_ring *br, void *new) static __inline void * buf_ring_peek(struct buf_ring *br) { -#ifdef DEBUG_BUFRING - if ((br->br_lock != NULL) && !mtx_owned(br->br_lock)) - panic("lock not held on single consumer dequeue"); +#ifdef CONFIG_LIBUKRING_DEBUG_BUFRING + if (!uk_mutex_is_locked(br->br_lock)) + UK_CRASH("lock not held on single consumer dequeue"); #endif /* @@ -321,17 +327,17 @@ buf_ring_peek(struct buf_ring *br) static __inline void * buf_ring_peek_clear_sc(struct buf_ring *br) { -#ifdef DEBUG_BUFRING +#ifdef CONFIG_LIBUKRING_DEBUG_BUFRING void *ret; - if (!mtx_owned(br->br_lock)) - panic("lock not held on single consumer dequeue"); + if (!uk_mutex_is_locked(br->br_lock)) + UK_CRASH("lock not held on single consumer dequeue"); #endif if (br->br_cons_head == br->br_prod_tail) return NULL; -#if defined(__arm__) || defined(__aarch64__) +#if defined(CONFIG_ARCH_ARM_32) || defined(CONFIG_ARCH_ARM_64) /* * The barrier is required there on ARM and ARM64 to ensure, that * br->br_ring[br->br_cons_head] will not be fetched before the above @@ -342,10 +348,11 @@ buf_ring_peek_clear_sc(struct buf_ring *br) * conditional check will be true, so we will return previously fetched * (and invalid) buffer. */ - atomic_thread_fence_acq(); + #error "unsupported: atomic_thread_fence_acq()" + /* atomic_thread_fence_acq(); */ #endif -#ifdef DEBUG_BUFRING +#ifdef CONFIG_LIBUKRING_DEBUG_BUFRING /* * Single consumer, i.e. cons_head will not move while we are * running, so atomic_swap_ptr() is not necessary here. @@ -378,8 +385,8 @@ buf_ring_count(struct buf_ring *br) & br->br_prod_mask; } -struct buf_ring *buf_ring_alloc(int count, struct malloc_type *type, int flags, - struct mtx *); -void buf_ring_free(struct buf_ring *br, struct malloc_type *type); +struct buf_ring *buf_ring_alloc(int count, struct uk_alloc *a, int flags, + struct uk_mutex *lock); +void buf_ring_free(struct buf_ring *br, struct uk_alloc *a); -#endif \ No newline at end of file +#endif diff --git a/lib/ukring/ring.c b/lib/ukring/ring.c index e327bd7..2badb79 100644 --- a/lib/ukring/ring.c +++ b/lib/ukring/ring.c @@ -26,30 +26,29 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/kernel.h> -#include <sys/malloc.h> -#include <sys/ktr.h> -#include <sys/buf_ring.h> +#include <uk/ring.h> +#include <uk/assert.h> +#include <uk/alloc.h> +#include <uk/mutex.h> +#include <uk/config.h> +#include <uk/print.h> +#include <uk/essentials.h> struct buf_ring * -buf_ring_alloc(int count, struct malloc_type *type, int flags, struct mtx *lock) +buf_ring_alloc(int count, struct uk_alloc *a, int flags, struct uk_mutex *lock) { struct buf_ring *br; - KASSERT(powerof2(count), ("buf ring must be size power of 2")); - - br = malloc(sizeof(struct buf_ring) + count*sizeof(caddr_t), - type, flags|M_ZERO); + /* buf ring must be size power of 2 */ + UK_ASSERT(POWER_OF_2(count)); - if (br == NULL) + br = uk_malloc(a, sizeof(struct buf_ring) + count * sizeof(caddr_t)); + if (br == NULL) { + uk_pr_err("could not allocate ring\n"); return NULL; + } -#ifdef DEBUG_BUFRING +#ifdef CONFIG_LIBUKRING_DEBUG_BUFRING br->br_lock = lock; #endif @@ -62,7 +61,7 @@ buf_ring_alloc(int count, struct malloc_type *type, int flags, struct mtx *lock) } void -buf_ring_free(struct buf_ring *br, struct malloc_type *type) +buf_ring_free(struct buf_ring *br, struct uk_alloc *a) { - free(br, type); -} \ No newline at end of file + uk_free(a, br); +} -- 2.11.0
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |