|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [UNIKRAFT PATCH v3 3/5] lib/ukring: Adapt {ring.c, ring.h} to Unikraft
Hi Alexander,
I'm gonna fix the uk_preempt_*() calls on upstreaming:
critical_enter -> uk_preempt_disable
critical_exit -> uk_preempt_enable
Reviewed-by: Costin Lupu <costin.lupu@xxxxxxxxx>
On 7/23/20 3:49 PM, Alexander Jung wrote:
> 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);
> +}
>
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |