check correctness

This commit is contained in:
yan 2024-09-25 14:48:08 +08:00
parent f42ecfae91
commit 5daaace5f2
7 changed files with 187 additions and 15 deletions

View File

@ -15,9 +15,11 @@
#include <mm/nvm.h>
#include <ckpt/hybird_mem.h>
#include <ckpt/hot_pages_tracker.h>
#include <immintrin.h>
/* Global big kernel lock */
struct lock big_kernel_lock;
int start_rtm = false;
void run_test(void);
void init_fpu_owner_locks(void);
@ -129,6 +131,8 @@ void main(u64 mbmagic, paddr_t mbaddr)
#ifdef RESTORE_ENABLED
skip_create_root_thread:
#endif
start_rtm = true;
sched();
eret_to_thread(switch_context());
BUG("Should never be here!\n");

View File

@ -1,5 +1,9 @@
#pragma once
#define USE_TSX
// #define PRE_TOUCH
// #define PRINT_ABORT_COUNT
#ifndef __RTM__
#pragma GCC push_options
#pragma GCC target("rtm")
@ -15,6 +19,7 @@
#define _XABORT_NESTED (1 << 5)
#define _XABORT_CODE(x) (((x) >> 24) & 0xFF)
extern int start_rtm;
static __inline__ unsigned int __attribute__((__always_inline__))
_xbegin(void)

View File

@ -1,7 +1,7 @@
#pragma once
/* Should be set at boot time */
#define PLAT_CPU_NUM 2
#define PLAT_CPU_NUM 10
/* MSR Registers */
#define IA32_APIC_BASE 0x0000001b

View File

@ -3,6 +3,9 @@
#include <common/kprint.h>
#include <mm/buddy.h>
#include <mm/rmap.h>
#include <immintrin.h>
int split_abort_count = 0;
static struct page *get_buddy_chunk(struct phys_mem_pool *pool,
struct page *chunk)
@ -156,6 +159,25 @@ void init_buddy(struct phys_mem_pool *pool, struct page *start_page,
}
}
#pragma GCC push_options
#pragma GCC optimize ("O0")
__attribute__ ((unused)) static void buddy_get_pages_touch_vars(struct phys_mem_pool *pool, int cur_order, struct page *chunk) {
int tmp1 = pool->free_lists[cur_order].nr_free;
(void) tmp1;
struct page *buddy_chunk = get_buddy_chunk(pool, chunk);
(void) buddy_chunk;
if (buddy_chunk == NULL) {
return;
}
int tmp2 = buddy_chunk->order;
(void) tmp2;
int tmp3 = chunk->order;
(void) tmp3;
int tmp4 = pool->free_lists[buddy_chunk->order].nr_free;
(void) tmp4;
}
#pragma GCC pop_options
struct page *buddy_get_pages(struct phys_mem_pool *pool, int order)
{
int cur_order;
@ -169,7 +191,7 @@ struct page *buddy_get_pages(struct phys_mem_pool *pool, int order)
}
lock(&pool->buddy_lock);
#ifndef USE_TSX
/* Search a chunk (with just enough size) in the free lists. */
for (cur_order = order; cur_order < BUDDY_MAX_ORDER; ++cur_order) {
free_list = &(pool->free_lists[cur_order].free_list);
@ -196,6 +218,46 @@ struct page *buddy_get_pages(struct phys_mem_pool *pool, int order)
* which can meet the required size.
*/
page = split_chunk(pool, order, page);
#else
/* Search a chunk (with just enough size) in the free lists. */
for (cur_order = order; cur_order < BUDDY_MAX_ORDER; ++cur_order) {
free_list = &(pool->free_lists[cur_order].free_list);
if (!list_empty(free_list)) {
/* Get a free memory chunck from the free list */
page = list_entry(free_list->next, struct page, node);
break;
}
}
if (unlikely(page == NULL)) {
kwarn("[OOM] No enough memory in memory pool %p\n", pool);
goto out;
}
if (page->order == order) {
#ifdef PRE_TOUCH
buddy_get_pages_touch_vars(pool, cur_order, page);
#endif
int status;
redo:
if ((status = _xbegin()) == _XBEGIN_STARTED) {
list_del(&page->node);
pool->free_lists[cur_order].nr_free -= 1;
_xend();
} else {
split_abort_count++;
kdebug("[%s] abort status %d count %d\n", __func__, status, split_abort_count);
goto redo;
}
} else {
prepare_latest_log(pool,
ADD_PAGES,
(u64)page,
order, cur_order);
list_del(&page->node);
pool->free_lists[cur_order].nr_free -= 1;
page = split_chunk(pool, order, page);
}
#endif
/* Set information of pages followed by head */
for (int i = 0; i < (1 << order); i++) {

View File

@ -13,6 +13,28 @@
/* slab_pool is also static. We do not add the static modifier due to unit test. */
struct slab_pointer *slab_pool;
static struct lock slabs_locks[SLAB_MAX_ORDER + 1];
int slab_abort_count = 0;
struct slab_log_entry {
u8 commited;
void *free_list_head;
void *next_slot;
int current_free_cnt;
u8 from_init;
void *current_slab;
int order;
};
static void prepare_slab_log(struct slab_log_entry *log, void *free_list_head, int current_free_count, void *next_slot, int order) {
log->commited = false;
log->free_list_head = free_list_head;
log->current_free_cnt = current_free_count;
log->order = order;
}
static void commit_slab_log(struct slab_log_entry *log) {
log->commited = true;
}
/*
static inline int order_to_index(int order)
@ -133,49 +155,77 @@ static void choose_new_current_slab(struct slab_pointer *pool, int order)
}
}
#pragma GCC push_options
#pragma GCC optimize ("O0")
static void *alloc_in_slab_impl(int order)
{
struct slab_header *current_slab;
struct slab_slot_list* free_list;
void* next_slot;
int status;
struct slab_log_entry log;
lock(&slabs_locks[order]);
current_slab = slab_pool[order].current_slab;
log.from_init = false;
log.current_slab = current_slab;
/* When serving the first allocation request. */
if (unlikely(current_slab == NULL)) {
current_slab = init_slab_cache(order, SIZE_OF_ONE_SLAB);
if (current_slab == NULL) {
unlock(&slabs_locks[order]);
return NULL;
}
log.from_init = true;
log.current_slab = current_slab;
slab_pool[order].current_slab = current_slab;
}
redo:
status = _xbegin();
if (status == _XBEGIN_STARTED) {
free_list = (struct slab_slot_list*)current_slab->free_list_head;
BUG_ON(free_list == NULL);
next_slot = free_list->next_free;
free_list = (struct slab_slot_list*)current_slab->free_list_head;
BUG_ON(free_list == NULL);
prepare_slab_log(&log, current_slab->free_list_head, current_slab->current_free_cnt, next_slot, order);
next_slot = free_list->next_free;
current_slab->free_list_head = next_slot;
current_slab->current_free_cnt -= 1;
_xend();
#ifdef USE_TSX
if (start_rtm == true) {
int status;
#ifdef PRE_TOUCH
void *tmp1 = current_slab->free_list_head;
int tmp2 = current_slab->current_free_cnt;
(void) tmp1;
(void) tmp2;
#endif
redo:
if ((status = _xbegin()) == _XBEGIN_STARTED) {
current_slab->free_list_head = next_slot;
current_slab->current_free_cnt -= 1;
_xend();
} else {
// printk("[%s] abort status:%d tid:%d\n", __func__, status, smp_get_cpu_id());
slab_abort_count++;
kdebug("[%s] abort count %d status %d\n", __func__, slab_abort_count, status);
goto redo;
}
} else {
// printk("[%s] abort status:%d tid:%d\n", __func__, status, smp_get_cpu_id());
goto redo;
current_slab->free_list_head = next_slot;
current_slab->current_free_cnt -= 1;
}
#else
current_slab->free_list_head = next_slot;
current_slab->current_free_cnt -= 1;
#endif
/* When current_slab is full, choose a new slab as the current one. */
if (unlikely(current_slab->current_free_cnt == 0))
choose_new_current_slab(&slab_pool[order], order);
commit_slab_log(&log);
unlock(&slabs_locks[order]);
return (void *)free_list;
}
#pragma GCC pop_options
#if DETECTING_DOUBLE_FREE_IN_SLAB == ON
static int check_slot_is_free(struct slab_header *slab_header, struct slab_slot_list* slot)

View File

@ -24,6 +24,8 @@ target_compile_options(assert.bin PRIVATE -g3 -ggdb)
add_executable(udp_echo_server.bin udp_echo_server.c)
add_executable(tcp_echo_server.bin tcp_echo_server.c)
add_executable(tsx_test.bin tsx_test.c)
# TreeSLS
add_subdirectory(treesls)

View File

@ -0,0 +1,49 @@
#include <malloc.h>
#include <stdio.h>
#include <chcore/pmu.h>
#include <pthread.h>
#include <chcore/syscall.h>
#pragma GCC push_options
#pragma GCC optimize ("O0")
const int num_threads = 10;
void *work(void *arg) {
int i = *(int *)arg;
usys_set_affinity(-1, i);
usys_yield();
s64 start = 0, end = 0;
int size = 4096;
int count = 1000000 / num_threads;
pmu_clear_cnt();
start = pmu_read_real_cycle();
for (int i = 0; i < count; i++)
{
void *m = malloc(size);
(void)m;
}
end = pmu_read_real_cycle();
printf("tsx_test total %ld\n", end - start);
return NULL;
}
int main(int argc, char *argv[])
{
pthread_t threads[num_threads];
int thread_index[num_threads];
for (int i = 0; i < num_threads; i++) {
thread_index[i] = i;
if (pthread_create(&threads[i], NULL, work, thread_index + i) != 0) {
perror("Failed to create thread");
return 1;
}
}
for (int i = 0; i < num_threads; i++) {
pthread_join(threads[i], NULL);
}
return 0;
}
#pragma GCC pop_options