diff --git a/mentos/CMakeLists.txt b/mentos/CMakeLists.txt index 6f189d6..60ab086 100644 --- a/mentos/CMakeLists.txt +++ b/mentos/CMakeLists.txt @@ -17,6 +17,11 @@ set(BUDDY_SYSTEM_FILE ${PROJECT_SOURCE_DIR}/src/mem/libbuddysystem.a) # Add the memory option. option(USE_BUDDY_SYSTEM "Build using the buddysystem written by the user." OFF) +# Enables cache tracing. +option(ENABLE_CACHE_TRACE "Enables cache tracing." OFF) +# Enables memory allocation tracing. +option(ENABLE_ALLOC_TRACE "Enables memory allocation tracing." OFF) + # ============================================================================= # ASSEMBLY @@ -197,6 +202,18 @@ target_compile_definitions( __KERNEL__ ) +# ============================================================================= +# Enables cache tracing. +if(ENABLE_CACHE_TRACE) + target_compile_definitions(${KERNEL_NAME} PUBLIC ENABLE_CACHE_TRACE) +endif(ENABLE_CACHE_TRACE) + +# ============================================================================= +# Enables memory allocation tracing. +if(ENABLE_ALLOC_TRACE) + target_compile_definitions(${KERNEL_NAME} PUBLIC ENABLE_ALLOC_TRACE) +endif(ENABLE_ALLOC_TRACE) + # ============================================================================= # Set the list of valid scheduling options. set(SCHEDULER_TYPES SCHEDULER_RR SCHEDULER_PRIORITY SCHEDULER_CFS SCHEDULER_EDF SCHEDULER_RM) diff --git a/mentos/inc/mem/slab.h b/mentos/inc/mem/slab.h index bdd0752..67e3d6c 100644 --- a/mentos/inc/mem/slab.h +++ b/mentos/inc/mem/slab.h @@ -9,9 +9,6 @@ #include "stddef.h" #include "mem/gfp.h" -//#define ENABLE_CACHE_TRACE -//#define ENABLE_ALLOC_TRACE - /// @brief Type for slab flags. typedef unsigned int slab_flags_t; @@ -88,10 +85,6 @@ void kmem_cache_destroy(kmem_cache_t *cachep); #ifdef ENABLE_CACHE_TRACE -#ifndef __FILENAME__ -#define __FILENAME__ (__builtin_strrchr(__FILE__, '/') ? __builtin_strrchr(__FILE__, '/') + 1 : __FILE__) -#endif - /// @brief Allocs a new object using the provided cache. /// @param file File where the object is allocated. /// @param fun Function where the object is allocated. @@ -109,10 +102,10 @@ void *pr_kmem_cache_alloc(const char *file, const char *fun, int line, kmem_cach void pr_kmem_cache_free(const char *file, const char *fun, int line, void *addr); /// Wrapper that provides the filename, the function and line where the alloc is happening. -#define kmem_cache_alloc(...) pr_kmem_cache_alloc(__FILENAME__, __func__, __LINE__, __VA_ARGS__) +#define kmem_cache_alloc(...) pr_kmem_cache_alloc(__FILE__, __func__, __LINE__, __VA_ARGS__) /// Wrapper that provides the filename, the function and line where the free is happening. -#define kmem_cache_free(...) pr_kmem_cache_free(__FILENAME__, __func__, __LINE__, __VA_ARGS__) +#define kmem_cache_free(...) pr_kmem_cache_free(__FILE__, __func__, __LINE__, __VA_ARGS__) #else /// @brief Allocs a new object using the provided cache. @@ -129,10 +122,6 @@ void kmem_cache_free(void *addr); #ifdef ENABLE_ALLOC_TRACE -#ifndef __FILENAME__ -#define __FILENAME__ (__builtin_strrchr(__FILE__, '/') ? __builtin_strrchr(__FILE__, '/') + 1 : __FILE__) -#endif - /// @brief Provides dynamically allocated memory in kernel space. /// @param file File where the object is allocated. /// @param fun Function where the object is allocated. @@ -149,10 +138,10 @@ void *pr_kmalloc(const char *file, const char *fun, int line, unsigned int size) void pr_kfree(const char *file, const char *fun, int line, void *addr); /// Wrapper that provides the filename, the function and line where the alloc is happening. -#define kmalloc(...) pr_kmalloc(__FILENAME__, __func__, __LINE__, __VA_ARGS__) +#define kmalloc(...) pr_kmalloc(__FILE__, __func__, __LINE__, __VA_ARGS__) /// Wrapper that provides the filename, the function and line where the free is happening. -#define kfree(...) pr_kfree(__FILENAME__, __func__, __LINE__, __VA_ARGS__) +#define kfree(...) pr_kfree(__FILE__, __func__, __LINE__, __VA_ARGS__) #else diff --git a/mentos/src/hardware/timer.c b/mentos/src/hardware/timer.c index e0c6df4..2c5ef10 100644 --- a/mentos/src/hardware/timer.c +++ b/mentos/src/hardware/timer.c @@ -158,11 +158,10 @@ void dynamic_timers_install() tvec_base_t *base = &cpu_base; base->timer_ticks = 0; - for(int i = 0; i < TVR_SIZE; ++i) + for (int i = 0; i < TVR_SIZE; ++i) list_head_init(base->tv1.vec + i); - for(int i = 0; i < TVN_SIZE; ++i) { - + for (int i = 0; i < TVN_SIZE; ++i) { list_head_init(base->tv2.vec + i); list_head_init(base->tv3.vec + i); list_head_init(base->tv4.vec + i); @@ -175,8 +174,8 @@ void dynamic_timers_install() } /// Prints used slots of timer vector -static void __print_tvec_slots(tvec_base_t *base, int tv_index) { - +static void __print_tvec_slots(tvec_base_t *base, int tv_index) +{ if (tv_index < 0 || tv_index > 5) return; @@ -184,51 +183,57 @@ static void __print_tvec_slots(tvec_base_t *base, int tv_index) { char result[TVN_SIZE + 1]; result[TVN_SIZE] = '\0'; - struct timer_vec* tv = NULL; - switch(tv_index) { - - // Root - case 1: { - - pr_debug("base->tv1.vec:"); - for(int i = 0; i < TVR_SIZE; ++i) { + struct timer_vec *tv = NULL; + switch (tv_index) { + // Root + case 1: { + pr_debug("base->tv1.vec:"); + for (int i = 0; i < TVR_SIZE; ++i) { + // New line in order to not clutter the screen + int index = i % TVN_SIZE; + if (i != 0 && index == 0) + pr_debug("\n\t%s", result); - // New line in order to not clutter the screen - int index = i % TVN_SIZE; - if (i != 0 && index == 0) - pr_debug("\n\t%s", result); + if (!list_head_empty(base->tv1.vec + i)) + result[index] = '1'; + else + result[index] = '0'; + } - if (!list_head_empty(base->tv1.vec + i)) - result[index] = '1'; - else - result[index] = '0'; - } + // The last line + pr_debug("\n\t%s\n", result); + return; - // The last line - pr_debug("\n\t%s\n", result); - return; + } break; - } break; - - // Normal - case 2: tv = &base->tv2; break; - case 3: tv = &base->tv3; break; - case 4: tv = &base->tv4; break; - case 5: tv = &base->tv5; break; + // Normal + case 2: + tv = &base->tv2; + break; + case 3: + tv = &base->tv3; + break; + case 4: + tv = &base->tv4; + break; + case 5: + tv = &base->tv5; + break; } - for(int i = 0; i < TVN_SIZE; ++i) { + for (int i = 0; i < TVN_SIZE; ++i) { if (list_head_empty(tv->vec + i)) result[i] = '0'; else result[i] = '1'; } - + pr_debug("base->tv%d.vec:\n\t%s\n", tv_index, result); } /// Dump all timer vector in base -static inline void __dump_all_tvec_slots(tvec_base_t *base) { +static inline void __dump_all_tvec_slots(tvec_base_t *base) +{ __print_tvec_slots(base, 1); __print_tvec_slots(base, 2); __print_tvec_slots(base, 3); @@ -238,13 +243,13 @@ static inline void __dump_all_tvec_slots(tvec_base_t *base) { /// Select correct timer vector and position inside of it for the input timer /// index contains the position inside of the tv_index timer vector -static void __find_tvec(tvec_base_t *base, struct timer_list *timer, int* index, int* tv_index) +static void __find_tvec(tvec_base_t *base, struct timer_list *timer, int *index, int *tv_index) { assert(index && "index is NULL"); assert(tv_index && "tv_index is NULL"); unsigned long expires = timer->expires; - unsigned long ticks = expires - base->timer_ticks; + unsigned long ticks = expires - base->timer_ticks; unsigned long tv1_ticks = TIMER_TICKS(0); unsigned long tv2_ticks = TIMER_TICKS(1); @@ -253,49 +258,59 @@ static void __find_tvec(tvec_base_t *base, struct timer_list *timer, int* index, // Can happen if you add a timer with expires == ticks, or in the past if ((signed long)ticks < 0) { - *index = base->timer_ticks & TVR_MASK; + *index = base->timer_ticks & TVR_MASK; *tv_index = 1; } // tv1 else if (ticks < tv1_ticks) { - *index = expires & TVR_MASK; + *index = expires & TVR_MASK; *tv_index = 1; } // tv2 else if (ticks < tv2_ticks) { - *index = (expires >> TIMER_TICKS_BITS(0)) & TVN_MASK; + *index = (expires >> TIMER_TICKS_BITS(0)) & TVN_MASK; *tv_index = 2; } // tv3 else if (ticks < tv3_ticks) { - *index = (expires >> TIMER_TICKS_BITS(1)) & TVN_MASK; + *index = (expires >> TIMER_TICKS_BITS(1)) & TVN_MASK; *tv_index = 3; } // tv4 else if (ticks < tv4_ticks) { - *index = (expires >> TIMER_TICKS_BITS(2)) & TVN_MASK; + *index = (expires >> TIMER_TICKS_BITS(2)) & TVN_MASK; *tv_index = 4; } // tv5 else { - *index = (expires >> TIMER_TICKS_BITS(3)) & TVN_MASK; + *index = (expires >> TIMER_TICKS_BITS(3)) & TVN_MASK; *tv_index = 5; } } /// Add timers into different lists based on their expire time -static void __add_timer_tvec_base(tvec_base_t *base, struct timer_list *timer) { - +static void __add_timer_tvec_base(tvec_base_t *base, struct timer_list *timer) +{ int index = 0, tv_index = 0; __find_tvec(base, timer, &index, &tv_index); - struct list_head* vec; - switch(tv_index) { - case 1: vec = base->tv1.vec + index; break; - case 2: vec = base->tv2.vec + index; break; - case 3: vec = base->tv3.vec + index; break; - case 4: vec = base->tv4.vec + index; break; - case 5: vec = base->tv5.vec + index; break; + struct list_head *vec; + switch (tv_index) { + case 1: + vec = base->tv1.vec + index; + break; + case 2: + vec = base->tv2.vec + index; + break; + case 3: + vec = base->tv3.vec + index; + break; + case 4: + vec = base->tv4.vec + index; + break; + case 5: + vec = base->tv5.vec + index; + break; } pr_debug("Adding timer at time_index: %d in tv%d\n", index, tv_index); @@ -304,22 +319,31 @@ static void __add_timer_tvec_base(tvec_base_t *base, struct timer_list *timer) { #ifdef ENABLE_REAL_TIMER_SYSTEM_DUMP __dump_all_tvec_slots(base); #endif - } /// Remove timer from tvec_base -static void __rem_timer_tvec_base(tvec_base_t *base, struct timer_list *timer) { - +static void __rem_timer_tvec_base(tvec_base_t *base, struct timer_list *timer) +{ int index = 0, tv_index = 0; __find_tvec(base, timer, &index, &tv_index); - struct list_head* vec; - switch(tv_index) { - case 1: vec = base->tv1.vec + index; break; - case 2: vec = base->tv2.vec + index; break; - case 3: vec = base->tv3.vec + index; break; - case 4: vec = base->tv4.vec + index; break; - case 5: vec = base->tv5.vec + index; break; + struct list_head *vec; + switch (tv_index) { + case 1: + vec = base->tv1.vec + index; + break; + case 2: + vec = base->tv2.vec + index; + break; + case 3: + vec = base->tv3.vec + index; + break; + case 4: + vec = base->tv4.vec + index; + break; + case 5: + vec = base->tv5.vec + index; + break; } pr_debug("Removing timer at time_index: %d in tv%d\n", index, tv_index); @@ -327,13 +351,12 @@ static void __rem_timer_tvec_base(tvec_base_t *base, struct timer_list *timer) { #ifdef ENABLE_REAL_TIMER_SYSTEM_DUMP __dump_all_tvec_slots(base); -#endif - +#endif } /// Move all timers from tv up one level -static int cascate(tvec_base_t* base, timer_vec* tv, int time_index, int tv_index) { - +static int cascate(tvec_base_t *base, timer_vec *tv, int time_index, int tv_index) +{ if (!list_head_empty(tv->vec + time_index)) { pr_debug("Relocating timers in tv%d.vec[%d]\n", tv_index, time_index); @@ -345,7 +368,6 @@ static int cascate(tvec_base_t* base, timer_vec* tv, int time_index, int tv_inde __add_timer_tvec_base(base, timer); } - } return time_index; } @@ -360,17 +382,15 @@ void run_timer_softirq() // While we are not up to date with current ticks unsigned long current_ticks = timer_get_ticks(); while (base->timer_ticks <= current_ticks) { - // Index of the current timer to execute int current_time_index = base->timer_ticks & TVR_MASK; // If the index is zero then all lists in base->tv1 have been checked, so they are empty if (!current_time_index) { - - // Consider the first invocation of the cascade() function: it receives as arguments + // Consider the first invocation of the cascade() function: it receives as arguments // the address in base, the address of base->tv2, and the index of the list // in base->tv2 including the timers that will decay in the next 256 ticks. This - // index is determined by looking at the proper bits of the base->timer_ticks value. + // index is determined by looking at the proper bits of the base->timer_ticks value. // cascade() moves all dynamic timers in the base->tv2 list into the // proper lists of base->tv1; then, it returns a positive value, unless all base->tv2 // lists are now empty. If so, cascade() is invoked once more to replenish @@ -381,16 +401,17 @@ void run_timer_softirq() int tv4_index = (base->timer_ticks >> TIMER_TICKS_BITS(2)) & TVN_MASK; int tv5_index = (base->timer_ticks >> TIMER_TICKS_BITS(3)) & TVN_MASK; - if (!cascate(base, &base->tv2, tv2_index, 2) && - !cascate(base, &base->tv3, tv3_index, 3) && - !cascate(base, &base->tv4, tv4_index, 4) && - !cascate(base, &base->tv5, tv5_index, 5)); + if (!cascate(base, &base->tv2, tv2_index, 2) && + !cascate(base, &base->tv3, tv3_index, 3) && + !cascate(base, &base->tv4, tv4_index, 4) && + !cascate(base, &base->tv5, tv5_index, 5)) + ; } // If there are timers to execute in this instant if (!list_head_empty(&base->tv1.vec[current_time_index])) { - pr_notice("Executing dynamic timers at %d ticks from start inside of tv1.vec[%d]\n", - base->timer_ticks, current_time_index); + pr_debug("Executing dynamic timers at %d ticks from start inside of tv1.vec[%d]\n", + base->timer_ticks, current_time_index); // Trigger all timers struct list_head *it, *tmp; @@ -399,7 +420,7 @@ void run_timer_softirq() // Executes timer function spinlock_unlock(&base->lock); - pr_notice("Executing dynamic timer function...\n"); + pr_debug("Executing dynamic timer function...\n"); timer->function(timer->data); spinlock_lock(&base->lock); @@ -426,12 +447,12 @@ void run_timer_softirq() // Executes timer function spinlock_unlock(&base->lock); - pr_notice("Executing dynamic timer function...\n"); + pr_debug("Executing dynamic timer function...\n"); timer->function(timer->data); spinlock_lock(&base->lock); // Removes timer from list - pr_notice("Removing dynamic timer...\n"); + pr_debug("Removing dynamic timer...\n"); list_head_del(it); kfree(timer); } @@ -453,27 +474,25 @@ void init_timer(struct timer_list *timer) void add_timer(struct timer_list *timer) { tvec_base_t *base = &cpu_base; - timer->base = base; + timer->base = base; #ifdef ENABLE_REAL_TIMER_SYSTEM __add_timer_tvec_base(base, timer); #else list_head_add_tail(&timer->entry, &base->list); #endif - } void del_timer(struct timer_list *timer) { tvec_base_t *base = &cpu_base; - timer->base = NULL; + timer->base = NULL; #ifdef ENABLE_REAL_TIMER_SYSTEM __rem_timer_tvec_base(base, timer); #else list_head_del(&timer->entry); #endif - } //====================================================================================== @@ -483,8 +502,7 @@ void del_timer(struct timer_list *timer) /// @param data The data. static inline void debug_timeout(unsigned long data) { - pr_notice("Il timer รจ stato attivato con successo: %d, ticks: %d, seconds: %d\n", - data, timer_ticks, timer_get_seconds()); + pr_debug("The timer has been successfully deactivated: %d, ticks: %d, seconds: %d\n", data, timer_ticks, timer_get_seconds()); } /// @brief Contains the entry of a wait queue and timespec which keeps trakc of @@ -497,7 +515,7 @@ typedef struct sleep_data_t { } sleep_data_t; /// @brief Callback for when a sleep timer expires -/// @param data Custom data stored in the timer +/// @param data Custom data stored in the timer void sleep_timeout(unsigned long data) { // NOTE: We could modify the sleep_on and make it return the wait_queue_entry_t @@ -550,7 +568,7 @@ int sys_nanosleep(const timespec *req, timespec *rem) } /// @brief Function executed when the real_timer of a process expires, sends SIGALRM to process. -/// @param pid PID of the process whos associated timer has expired +/// @param pid PID of the process whos associated timer has expired void alarm_timeout(unsigned long pid) { sys_kill(pid, SIGALRM); diff --git a/mentos/src/mem/slab.c b/mentos/src/mem/slab.c index 2e2b847..119073c 100644 --- a/mentos/src/mem/slab.c +++ b/mentos/src/mem/slab.c @@ -263,7 +263,7 @@ void *kmem_cache_alloc(kmem_cache_t *cachep, gfp_t flags) list_head_add(slab_full_elem, &cachep->slabs_full); } #ifdef ENABLE_CACHE_TRACE - pr_notice("kmem_cache_alloc : (%-16s:%3d)[%-16s] : 0x%p\n", file, line, cachep->name, ptr); + pr_notice("CHACE-ALLOC 0x%p in %-20s at %s:%d\n", ptr, cachep->name, file, line); #endif return ptr; } @@ -284,7 +284,7 @@ void kmem_cache_free(void *ptr) kmem_cache_t *cachep = slab_page->container.slab_cache; #ifdef ENABLE_CACHE_TRACE - pr_notice("kmem_cache_free : (%-16s:%3d)[%-16s] : 0x%p\n", file, line, cachep->name, ptr); + pr_notice("CHACE-FREE 0x%p in %-20s at %s:%d\n", ptr, cachep->name, file, line); #endif if (cachep->dtor) cachep->dtor(ptr); @@ -332,7 +332,7 @@ void *kmalloc(unsigned int size) ptr = kmem_cache_alloc(malloc_blocks[order], GFP_KERNEL); } #ifdef ENABLE_ALLOC_TRACE - pr_notice("kmalloc : (%-16s:%3d) : 0x%p\n", file, line, ptr); + pr_notice("KMALLOC 0x%p at %s:%d\n", ptr, file, line); #endif return ptr; } @@ -344,7 +344,7 @@ void kfree(void *ptr) #endif { #ifdef ENABLE_ALLOC_TRACE - pr_notice("kfree : (%-16s:%3d) : 0x%p\n", file, line, ptr); + pr_notice("KFREE 0x%p at %s:%d\n", ptr, file, line); #endif page_t *page = get_lowmem_page_from_address((uint32_t)ptr); diff --git a/mentos/src/system/signal.c b/mentos/src/system/signal.c index 7bc5135..e83eba0 100644 --- a/mentos/src/system/signal.c +++ b/mentos/src/system/signal.c @@ -360,7 +360,7 @@ static void __do_signal_stop(struct task_struct *current, struct pt_regs *f, int // the SA_NOCLDSTOP flag of SIGCHLD. if (!(SA_NOCLDSTOP & current->parent->sighand.action[SIGCHLD - 1].sa_flags)) if (__notify_parent(current, SIGCHLD) != 0) - pr_debug("Failed to notify parent with signal: %d", signr); + pr_warning("Failed to notify parent with signal: %d", signr); // The state is now TASK_UNINTERRUPTABLE sleep_on(&stopped_queue); @@ -410,7 +410,7 @@ int do_signal(struct pt_regs *f) // If its value is 0, it means that all pending signals have been // handled and do_signal( ) can finish. if (signr == 0) { - pr_notice("There are no more signals to handle.\n"); + pr_debug("There are no more signals to handle.\n"); __unlock_task_sighand(current); return 0; } @@ -633,7 +633,7 @@ int sys_kill(pid_t pid, int sig) sighandler_t sys_signal(int signum, sighandler_t handler) { - pr_notice("sys_signal(%d, %p)\n", signum, handler); + pr_debug("sys_signal(%d, %p)\n", signum, handler); // Check the signal that we want to send. if ((signum < 0) || (signum >= NSIG)) { pr_err("sys_signal(%d, %p): Wrong signal number!\n", signum, handler); @@ -645,7 +645,7 @@ sighandler_t sys_signal(int signum, sighandler_t handler) assert(current && "There is no running process."); // Skip the `init` process, always. if (current->pid == 1) { - pr_err("sys_signal(%d, %p): Cannot signal number!\n", signum, handler); + pr_err("sys_signal(%d, %p): Cannot signal init!\n", signum, handler); return SIG_ERR; } // Create a new signal action. @@ -677,7 +677,7 @@ int sys_sigaction(int signum, const sigaction_t *act, sigaction_t *oldact) pr_debug("sys_sigaction(%d, %p, %p)\n", signum, act, oldact); // Check the signal that we want to send. if ((signum < 0) || (signum >= NSIG)) { - pr_debug("sys_sigaction(%d, %p, %p): Wrong signal number!\n", signum, act, oldact); + pr_err("sys_sigaction(%d, %p, %p): Wrong signal number!\n", signum, act, oldact); return -EINVAL; } // The do_signal() function is usually only invoked when the CPU is going @@ -686,7 +686,7 @@ int sys_sigaction(int signum, const sigaction_t *act, sigaction_t *oldact) assert(current && "There is no running process."); // Skip the `init` process, always. if (current->pid == 1) { - pr_debug("sys_sigaction(%d, %p, %p): Cannot set signal for init!\n", signum, act, oldact); + pr_err("sys_sigaction(%d, %p, %p): Cannot set signal for init!\n", signum, act, oldact); return -EINVAL; } // Lock the signal handling for the given task. @@ -708,7 +708,7 @@ int sys_sigaction(int signum, const sigaction_t *act, sigaction_t *oldact) int sys_sigprocmask(int how, const sigset_t *set, sigset_t *oldset) { - pr_notice("sys_sigprocmask(%d, %p, %p)\n", how, set, oldset); + pr_debug("sys_sigprocmask(%d, %p, %p)\n", how, set, oldset); if (!set && !oldset) { return -EFAULT; } @@ -721,7 +721,7 @@ int sys_sigprocmask(int how, const sigset_t *set, sigset_t *oldset) assert(current && "There is no running process."); // Skip the `init` process, always. if (current->pid == 1) { - pr_notice("sys_sigprocmask(%d, %p, %p): Cannot set signal for init!\n", how, set, oldset); + pr_warning("sys_sigprocmask(%d, %p, %p): Cannot set signal for init!\n", how, set, oldset); return -EINVAL; } // If `oldset` is not, return the old set.