#include "mm.h"
+// The following can be used to track heap bugs
+// zero memory after allocation
+#define ALLOC_ZERO_MEM 0
+// pad allocations by this many bytes on both ends of block
+#define ALLOC_PAD 0
+
u32 pg_allocs = 0;
u32 pg_frees = 0;
}
+void *
+palacios_alloc_extended(unsigned int size, unsigned int flags) {
+ void * addr = NULL;
+
+ addr = kmalloc(size+2*ALLOC_PAD, flags);
+
+ if (!addr) {
+ ERROR("ALERT ALERT kmalloc has FAILED FAILED FAILED\n");
+ return NULL;
+ }
+
+ mallocs++;
+
+#if ALLOC_ZERO_MEM
+ memset(addr,0,size+2*ALLOC_PAD);
+#endif
+
+ return addr+ALLOC_PAD;
+}
+
+
/**
* Allocates 'size' bytes of kernel memory.
* Returns the kernel virtual address of the memory allocated.
*/
void *
palacios_alloc(unsigned int size) {
- void * addr = NULL;
// It is very important that this test remains since
// this function is used extensively throughout palacios and the linux
// module, both in places where interrupts are off and where they are on
// a GFP_KERNEL call, when done with interrupts off can lead to DEADLOCK
if (irqs_disabled()) {
- addr = kmalloc(size, GFP_ATOMIC);
+ return palacios_alloc_extended(size,GFP_ATOMIC);
} else {
- addr = kmalloc(size, GFP_KERNEL);
+ return palacios_alloc_extended(size,GFP_KERNEL);
}
- if (!addr) {
- ERROR("ALERT ALERT kmalloc has FAILED FAILED FAILED\n");
- return NULL;
- }
-
- mallocs++;
-
- return addr;
}
/**
)
{
frees++;
- kfree(addr);
+ kfree(addr-ALLOC_PAD);
return;
}
return;
}
+
+#define MAX_THREAD_NAME 32
+
struct lnx_thread_arg {
int (*fn)(void * arg);
void * arg;
- char * name;
+ char name[MAX_THREAD_NAME];
};
static int lnx_thread_target(void * arg) {
thread_info->fn = fn;
thread_info->arg = arg;
- thread_info->name = thread_name;
+ strncpy(thread_info->name,thread_name,MAX_THREAD_NAME);
+ thread_info->name[MAX_THREAD_NAME-1] =0;
- return kthread_run( lnx_thread_target, thread_info, thread_name );
+ return kthread_run( lnx_thread_target, thread_info, thread_info->name );
}
thread_info->fn = fn;
thread_info->arg = arg;
- thread_info->name = thread_name;
+ strncpy(thread_info->name,thread_name,MAX_THREAD_NAME);
+ thread_info->name[MAX_THREAD_NAME-1] =0;
-
- thread = kthread_create( lnx_thread_target, thread_info, thread_name );
+ thread = kthread_create( lnx_thread_target, thread_info, thread_info->name );
if (IS_ERR(thread)) {
- WARNING("Palacios error creating thread: %s\n", thread_name);
+ WARNING("Palacios error creating thread: %s\n", thread_info->name);
palacios_free(thread_info);
return NULL;
}
* Given now immediately if there is no other thread that is runnable
* And there is no real bound on how long it will yield
*/
-void palacios_yield_cpu_timed(unsigned int us)
+void palacios_sleep_cpu(unsigned int us)
{
- unsigned int uspj = 1000000U/HZ;
-
- unsigned int jiffies = us/uspj + ((us%uspj) !=0); // ceiling
-
set_current_state(TASK_INTERRUPTIBLE);
-
- schedule_timeout(jiffies);
-
+ if (us) {
+ unsigned int uspj = 1000000U/HZ;
+ unsigned int jiffies = us/uspj + ((us%uspj) !=0); // ceiling
+ schedule_timeout(jiffies);
+ } else {
+ schedule();
+ }
+ return;
}
+void palacios_wakeup_cpu(void *thread)
+{
+ wake_up_process(thread);
+ return;
+}
/**
* Allocates a mutex.
.get_cpu_khz = palacios_get_cpu_khz,
.start_kernel_thread = palacios_start_kernel_thread,
.yield_cpu = palacios_yield_cpu,
- .yield_cpu_timed = palacios_yield_cpu_timed,
+ .sleep_cpu = palacios_sleep_cpu,
+ .wakeup_cpu = palacios_wakeup_cpu,
.mutex_alloc = palacios_mutex_alloc,
.mutex_free = palacios_mutex_free,
.mutex_lock = palacios_mutex_lock,