Question

I'm new to Kernel programming and programming with locks.

Is it safe to lock and unlock a spinlock in different functions? I am doing this to synchronize the code flow.

Also, is it safe to use spinlock (lock & unlock) in __schedule()? Is it safe to keep the scheduler waiting to acquire a lock?

Thanks in advance.

Was it helpful?

Solution

Instead of spinlock, you can use a semaphore or a mutex. You should use spinlock in the same function for the littlest set of operations.

OTHER TIPS

A good reason of NOT using spinlock / unlock from different function isn't so obvious. One big and a very-very good reason not to to it it's the fact that when you spinlock on it sets a flag ATOMIC in a scheduler struct - and your kernel becomes ATOMIC context from this moment and up to moment you unlock the spinlock. Try it with the kernel compiled with debug flags - you'll see a lot of BUG messages in your klog.

Good luck.

If you design your code correctly, there is no harm in acquiring and releasing the same spinlock from multiple locations, in fact, that's pretty much the point of it; you can use a single spinlock to implement a set of functions that are similar to the Linux atomic operations but with whatever additional internal complexity you need. As long as within each function you acquire and release the lock around the shared resource(s), it should work just fine.

The main considerations are:

  1. keep the code between each claim/release pair as brief as possible - it's an atomic context
  2. this will work fine on a single core system and scale to pre-emptive SMP
  3. you still need to consider what type of code you are implementing and what context(s) it might be running on, and use the correct type of spinlock for that

As long as you treat spinlocks with care - keeping in mind the potential for deadlocks - and understand that anything you do within the spinlock can affect system latency, then they are a very useful tool.

If you know that all the areas in your code where you've claimed the lock always complete and release quickly then you can be equally sure that any other bit of your code won't ever be spinning for ages waiting on the lock. This is potentially much more efficient that using a mutex.

The other value of taking the spinlock is that it acts as an implicit memory barrier, so by taking a lock around manipulating some resource (e.g. a member of a structure) you can be sure that any other thread through your code which also takes the lock before reading/writing that resource is seeing the current state of it, and not some out-of-date value due to cache coherency issues.

It's a potentially complex subject but hopefully that explanation helps a bit.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top