diff --git a/kernel-src/io/net/vionet.c b/kernel-src/io/net/vionet.c index 9d10c277..400849e6 100644 --- a/kernel-src/io/net/vionet.c +++ b/kernel-src/io/net/vionet.c @@ -230,6 +230,8 @@ int vionet_newdevice(viodevice_t *viodevice) { char name[10]; snprintf(name, 10, "vionet%d", netdev->id); + netdev->netdev.flags = NETDEV_FLAGS_UP | NETDEV_FLAGS_BROADCAST | NETDEV_FLAGS_RUNNING; + __assert(netdev_register((netdev_t *)netdev, name) == 0); return 0; diff --git a/kernel-src/mm/alloc.c b/kernel-src/mm/alloc.c index e213c726..ccab32c2 100644 --- a/kernel-src/mm/alloc.c +++ b/kernel-src/mm/alloc.c @@ -4,28 +4,37 @@ #include #include -// each allocation has the following structure: -// ptr: data capacity (allocsizes size) -// ptr + sizeof(size_t): current size -// ptr + sizeof(size_t) * 2: data -// ptr + datasize: poison value - -#define USE_POISON 0 +#define DEBUG 1 #define POISON_VALUE 0xdeadbeefbadc0ffel #define CACHE_COUNT 14 -#define CAPACITY_SIZE(cache) cache->size - sizeof(size_t) * 2 - USE_POISON * sizeof(size_t) +#if DEBUG == 1 +typedef struct { + size_t capacity; + size_t current_size; + size_t debug_address; + uint8_t data[]; +} alloc_header_t; +#else +typedef struct { + size_t capacity; + size_t current_size; + uint8_t data[]; +} alloc_header_t; +#endif + +#define CAPACITY_SIZE(cache) cache->size - sizeof(alloc_header_t) - DEBUG * sizeof(size_t); static size_t allocsizes[CACHE_COUNT] = {32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144}; static scache_t *caches[CACHE_COUNT + 5]; static void initarea(scache_t *cache, void *obj, size_t size) { - size_t *ptr = obj; - *ptr = CAPACITY_SIZE(cache); - *(ptr + 1) = size; - memset(ptr + 2, 0, *ptr); - #if USE_POISON == 1 - *((size_t *)((uintptr_t)obj + cache->size - sizeof(size_t))) = POISON_VALUE; + alloc_header_t *hdr = obj; + hdr->capacity = CAPACITY_SIZE(cache); + hdr->current_size = size; + memset(hdr->data, 0, hdr->capacity); + #if DEBUG == 1 + *((size_t *)((uintptr_t)obj + cache->size - 1 * sizeof(size_t))) = POISON_VALUE; #endif } @@ -33,61 +42,74 @@ static scache_t *getcachefromsize(size_t size) { if (unlikely(size <= 1)) return caches[0]; + if (unlikely(size > 262144)) + return NULL; + size_t i = 64 - __builtin_clzll(size - 1); return caches[i]; } void *alloc(size_t size) { scache_t *cache = getcachefromsize(size); - size_t *ret = slab_allocate(cache); + if (unlikely(cache == NULL)) + return NULL; + + alloc_header_t *ret = slab_allocate(cache); if (unlikely(ret == NULL)) return NULL; initarea(cache, ret, size); - #if USE_POISON == 1 - __assert(*ret == CAPACITY_SIZE(cache)); + #if DEBUG == 1 + __assert(*(size_t *)((uintptr_t)ret + cache->size - sizeof(size_t)) == POISON_VALUE); + ret->debug_address = (size_t)__builtin_return_address(0); #endif - return ret + 2; + return ret->data; } void free(void *ptr) { - slab_free(getcachefromsize(*((size_t *)ptr - 2)), (size_t *)ptr - 2); + alloc_header_t *header = container_of(ptr, alloc_header_t, data); + scache_t *cache = getcachefromsize(header->capacity); + #if DEBUG == 1 + __assert(cache); + header->current_size = 0; + __assert(*(size_t *)((uintptr_t)header + cache->size - sizeof(size_t)) == POISON_VALUE); + #endif + slab_free(cache, header); } void *realloc(void *ptr, size_t size) { - size_t *start = ptr; - start -= 2; - size_t currentsize = *(start + 1); - if (size <= currentsize) { - *(start + 1) = size; + alloc_header_t *header = container_of(ptr, alloc_header_t, data); + if (size <= header->capacity) { + header->current_size = size; return ptr; } // grow - scache_t *oldcache = getcachefromsize(*start); - scache_t *newcache = getcachefromsize(size); + scache_t *old_cache = getcachefromsize(header->capacity); + scache_t *new_cache = getcachefromsize(size); // same allocation - if (oldcache == newcache) { - size_t diff = size - currentsize; - memset((void *)((uintptr_t)ptr + currentsize), 0, diff); - *(start + 1) = size; + if (old_cache == new_cache) { + size_t diff = size - header->current_size; + memset((void *)((uintptr_t)ptr + header->current_size), 0, diff); + header->current_size = size; return ptr; } // different allocation - size_t *new = slab_allocate(newcache); + alloc_header_t *new = slab_allocate(new_cache); if (new == NULL) return NULL; - initarea(newcache, new, size); - memcpy((new + 2), ptr, currentsize); - slab_free(oldcache, start); - return new + 2; + + initarea(new_cache, new, size); + memcpy(new->data, ptr, header->current_size); + slab_free(old_cache, header); + return new->data; } void alloc_init() { for (int i = 0; i < CACHE_COUNT; ++i) { - caches[i + 5] = slab_newcache(allocsizes[i] + sizeof(size_t) * 2 + sizeof(size_t) * USE_POISON, 0, NULL, NULL); + caches[i + 5] = slab_newcache(allocsizes[i] + sizeof(alloc_header_t) + sizeof(size_t) * DEBUG, 0, NULL, NULL); __assert(caches[i + 5]); void *p = slab_allocate(caches[i + 5]); __assert(p);