I made all my register functions inline and also replaced xchg with spin_lock and spin_unlock. But that did not help. I am having the same result.
To clarify the confusion, I actually run a userspace program that calls the module's open routine which registers the hook. So registration is actually done by the module.
However, this time I have something for you. I ran the module and program from console instead of running in GUI and it looks like the kernel actually panics when it freezes the system. Part of the output I could write down goes below -
----------------------------------------
EIP: [<60455670>] free_fdtable_rcu + 0xd/0x75 SS:ESP
0068: f5c71f10
kernel_panic - not syncing: Fatal exception in interrupt
-----------------------------------------
This happens with both 4k and 8k stacks with/without inline register functions.
-------------------------------------------
/* Timer hook to use with klife */
#define CONFIG_GAMEOFLIFE
struct timer_interrupt_hook
{
void (*func)(void*);
void* data;
};
spinlock_t timer_lock = SPIN_LOCK_UNLOCKED;
static struct timer_interrupt_hook *timer_interrupt_hook;
static inline int register_timer_interrupt(struct timer_interrupt_hook *hook)
{
unsigned long flags;
pr_debug("registering timer_interrupt_hook (%p), hook->func (%p), hook->data (%p)\n", hook, hook->func, hook->data);
spin_lock_irqsave(&timer_lock, flags);
timer_interrupt_hook = hook;
spin_unlock_irqrestore(&timer_lock, flags);
return 0;
}
static inline void unregister_timer_interrupt(struct timer_interrupt_hook *hook)
{
unsigned long flags;
pr_debug("unregistering timer_interrupt_hook\n");
spin_lock_irqsave(&timer_lock, flags);
timer_interrupt_hook = 0;
spin_unlock_irqrestore(&timer_lock, flags);
}
static void call_timer_hook(void)
{
struct timer_interrupt_hook *hook = timer_interrupt_hook;
if (hook && hook->func)
hook->func(hook->data);
}
/*
* The 64-bit jiffies value is not atomic - you MUST NOT read it
* without sampling the sequence number in xtime_lock.
* jiffies is defined in the linker script...
*/
void do_timer(unsigned long ticks)
{
jiffies_64 += ticks;
update_times(ticks);
#ifdef CONFIG_GAMEOFLIFE
call_timer_hook();
#endif
}
-------------------------------------------
Thanks,
- Meraj
Mulyadi Santosa <mulyadi.santosa@xxxxxxxxx> wrote:
hello...
> Thanks for your reply. Regarding your suspects -
>
> 1. I am actually calling the register_timer_interrupt routine to register the hook only once by running the userspace program once that registers the hook. So there should not be any lock contention I think unless the lock is global in the kernel!!!
>
>
I didn't talk about the registration. I talked about do_timer() that
calls your hook (whether it's NULL or pointing to valid function). About
the lock, how do you know the lock isn't global? Even though (assume)
it's not global, but if many code paths use this lock, you still suffer
contention.
And please, no need for 3 exclamation marks. I can understand technical
objection without them, don't worry.
> 2. I can't think about why it would overflow kernel stack because do_timer() calls many other functions too and my registered hook is like any function call which is currently empty. So it should not take any time to execute it.
>
>
That was pure guess. And that's why I suggest to try enlarging your
stack size in case you use 4K stack. And using inline version of your
hook management function could probably help. If none of them helps,
then we can be fairly sure it's not stack problem
> 3. After I load the module, I run the userspace program which registers the hook and terminates. The system runs fine for about 5-10 secs after that before freezing.
>
>
hm wait2x, you said "userspace program registers the hook?" So where's
this hook function live? user space? kernel space? I am not clear about it.
BTW, about xchg(). Are you sure you need that? what if you just use
spinlock and/or disabling interrupt?
regards,
Mulyadi.
Catch up on fall's hot new shows on Yahoo! TV. Watch previews, get listings, and more!