kernel - insmod: page allocation failure -
i'm trying experiment aimed @ measuring code execution times on generic linux. however, after insmod
, dmesg
, see insmod: page allocation failure
, unable allocate memory times [25]
. can give me idea? what's wrong code? seem gets trouble when tries malloc.
#include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/hardirq.h> #include <linux/preempt.h> #include <linux/sched.h> #include <linux/slab.h> #define size_of_stat 100000 #define bound_of_loop 1000 #define uint64_max (18446744073709551615ull) void inline measured_function(volatile int *var) { (*var) = 1; } void inline filltimes(uint64_t **times) { unsigned long flags; int i, j; uint64_t start, end; unsigned cycles_low, cycles_high, cycles_low1, cycles_high1; volatile int variable = 0; asm volatile ("cpuid\n\t" "rdtsc\n\t" "mov %%edx, %0\n\t" "mov %%eax, %1\n\t": "=r" (cycles_high), "=r" (cycles_low):: "%rax", "%rbx", "%rcx", "%rdx"); asm volatile ("rdtscp\n\t" "mov %%edx, %0\n\t" "mov %%eax, %1\n\t": "=r" (cycles_high), "=r" (cycles_low):: "%rax", "%rbx", "%rcx", "%rdx"); asm volatile ("cpuid\n\t" "rdtsc\n\t" "mov %%edx, %0\n\t" "mov %%eax, %1\n\t": "=r" (cycles_high), "=r" (cycles_low):: "%rax", "%rbx", "%rcx", "%rdx"); asm volatile ("rdtscp\n\t" "mov %%edx, %0\n\t" "mov %%eax, %1\n\t" "cpuid\n\t": "=r" (cycles_high), "=r" (cycles_low):: "%rax", "%rbx", "%rcx", "%rdx"); (j=0; j<bound_of_loop; j++) { (i =0; i<size_of_stat; i++) { variable = 0; preempt_disable(); raw_local_irq_save(flags); asm volatile ( "cpuid\n\t" "rdtsc\n\t" "mov %%edx, %0\n\t" "mov %%eax, %1\n\t": "=r" (cycles_high), "=r" (cycles_low):: "%rax", "%rbx", "%rcx", "%rdx"); /*call function measure here*/ measured_function(&variable); asm volatile( "rdtscp\n\t" "mov %%edx, %0\n\t" "mov %%eax, %1\n\t" "cpuid\n\t": "=r" (cycles_high1), "=r" (cycles_low1):: "%rax", "%rbx", "%rcx", "%rdx"); raw_local_irq_restore(flags); preempt_enable(); start = ( ((uint64_t)cycles_high << 32) | cycles_low ); end = ( ((uint64_t)cycles_high1 << 32) | cycles_low1 ); if ( (end - start) < 0) { printk(kern_err "\n\n>>>>>>>>>>>>>> critical error in taking time!!!!!!\n loop(%d) stat(%d) start = %llu, end = %llu, variable = %u\n", j, i, start, end, variable); times[j][i] = 0; } else { times[j][i] = end - start; } } } return; } uint64_t var_calc(uint64_t *inputs, int size) { int i; uint64_t acc = 0, previous = 0, temp_var = 0; (i=0; i< size; i++) { if (acc < previous) goto overflow; previous = acc; acc += inputs[i]; } acc = acc * acc; if (acc < previous) goto overflow; previous = 0; (i=0; i< size; i++){ if (temp_var < previous) goto overflow; previous = temp_var; temp_var+= (inputs[i]*inputs[i]); } temp_var = temp_var * size; if (temp_var < previous) goto overflow; temp_var =(temp_var - acc)/(((uint64_t)(size))*((uint64_t)(size))); return (temp_var); overflow: printk(kern_err "\n\n>>>>>>>>>>>>>> critical overflow error in var_calc!!!!!!\n\n"); return -einval; } static int __init hello_start(void) { int = 0, j = 0, spurious = 0, k =0; uint64_t **times; uint64_t *variances; uint64_t *min_values; uint64_t max_dev = 0, min_time = 0, max_time = 0, prev_min =0, tot_var=0, max_dev_all=0, var_of_vars=0, var_of_mins=0; printk(kern_info "loading hello module...\n"); times = kmalloc(bound_of_loop*sizeof(uint64_t*), gfp_kernel); if (!times) { printk(kern_err "unable allocate memory times\n"); return 0; } (j=0; j<bound_of_loop; j++) { times[j] = kmalloc(size_of_stat*sizeof(uint64_t), gfp_kernel); if (!times[j]) { printk(kern_err "unable allocate memory times[%d]\n", j); (k=0; k<j; k++) kfree(times[k]); return 0; } } variances = kmalloc(bound_of_loop*sizeof(uint64_t), gfp_kernel); if (!variances) { printk(kern_err "unable allocate memory variances\n"); return 0; } min_values = kmalloc(bound_of_loop*sizeof(uint64_t), gfp_kernel); if (!min_values) { printk(kern_err "unable allocate memory min_values\n"); return 0; } filltimes(times); (j=0; j<bound_of_loop; j++) { max_dev = 0; min_time = 0; max_time = 0; (i =0; i<size_of_stat; i++) { if ((min_time == 0)||(min_time > times[j][i])) min_time = times[j][i]; if (max_time < times[j][i]) max_time = times[j][i]; } max_dev = max_time - min_time; min_values[j] = min_time; if ((prev_min != 0) && (prev_min > min_time)) spurious++; if (max_dev > max_dev_all) max_dev_all = max_dev; variances[j] = var_calc(times[j], size_of_stat); tot_var += variances[j]; printk(kern_err "loop_size:%d >>>> variance(cycles): %llu; max_deviation: %llu ;min time: %llu", j, variances[j], max_dev, min_time); prev_min = min_time; } var_of_vars = var_calc(variances, bound_of_loop); var_of_mins = var_calc(min_values, bound_of_loop); printk(kern_err "\n total number of spurious min values = %d", spurious); printk(kern_err "\n total variance = %llu", (tot_var/bound_of_loop)); printk(kern_err "\n absolute max deviation = %llu", max_dev_all); printk(kern_err "\n variance of variances = %llu", var_of_vars); printk(kern_err "\n variance of minimum values = %llu", var_of_mins); (j=0; j<bound_of_loop; j++) { kfree(times[j]); } kfree(times); kfree(variances); kfree(min_values); return 0; } static void __exit hello_end(void) { printk(kern_info "goodbye mr.\n"); } module_init(hello_start); module_exit(hello_end);
Comments
Post a Comment