Fixed kernel freezes. Read more...
Turns out kernel freezes were due to deadlock, which was caused by our private data lock. The spin_lock() function only disables preemption, but n-o-t interrupts, such as the timer_interrupt, thus our timer_callback() was called. When there is a huge number of page faults, some page faults would be very close to the timer handler, thus still holding the lock when timer interrupt occurs. When this happens, timer handler tries to lock, thus causing the deadlock.
I solved this by making the page fault handler use spin_lock_irq() instead. In the point we edit the page fault handler, interrupts are already allowed, so its ok to enable those by spin_unlock_irq(). This fixes the issue as now timer interrupt can only be called once the page fault handler isn't holding the lock.
Thus, project is almost done, only need to make code prettier, and perhaps allow a ioctl interface to take control of hash table size and locality size.