9

If a process holds some spinlocks or semaphores, and exit accidently(e.g., killed by linux), would linux release these locks correctly? If linux doesn't do this work, why?

silverbullettt
  • 846
  • 1
  • 10
  • 13
  • 1
    If you are interested in Linux architecture as it relates to synchronization mechanisms you might want to take a look at how the futex system call works ("man 7 futex", "man 2 futex"). both phtread_mutex and sem_wait are implemented with a futex in the blocking case. – Andrew Tomazos Mar 25 '12 at 04:12

1 Answers1

11

It depends on the type of lock you're talking about.

If you're talking about any kind of kernel internal lock, they will be released as appropriate (as your system would soon crash otherwise). In general these kind of locks are not owned by the process itself, but rather by some internal kernel workflow, and usually don't remain locked after the process returns to userspace anyway.

Note, however, that if the kernel is already deadlocked when you issue the kill, chances are the process won't be killed. Process killing is performed as part of the signal handling path, which is invoked from the kernel-to-userspace return transition code. If the process is waiting for a kernel spinlock, you'll never make it to the return code and so the process won't exit.

Additionally, if the process is killed because of a kernel OOPS, then all bets are off - the kernel is already in an inconsistent state, and the OOPS exit code doesn't try very hard to clean up any locks the kernel thread may have been holding at the time.

If you're talking about any sort of userspace spinlock or semaphore (including the sem_* family of IPC semaphores), no, they will not be released, as there is no concept of lock ownership with a semaphore.

If you're talking about the flock family of file locks, or fcntl(F_SETLK, ...) advisory locks, they will be automatically released when any file descriptor bound to the file in that process is closed. Because of this, flock is a bad idea to use in most cases, but yes, it would be released if the process was killed.

If you're talking about a process-local pthread_mutex, it's moot because the mutex will cease to exist along with the process.

If you're talking about a shared pthread_mutex in a shared memory segment (one in which pthread_mutexattr_setpshared has been used to make it sharable), it will be autoreleased only if it is also marked as a robust mutex, with pthread_mutexattr_setrobust - but it must be marked consistent before re-use; see the pthread_mutex_consistent manpage for details.

bdonlan
  • 224,562
  • 31
  • 268
  • 324
  • Thank you very much. I'm talking about kernel internal lock, because we want to relieve system lockup error. And these kind of locks are impactive when some error occur, especially spinlock(very destructive!!) – silverbullettt Mar 25 '12 at 14:47
  • @silverbullet, if you have a kernel deadlock you won't actually be able to kill the processes involved - killing a process requires an exit from kernel transition, since the SIGKILL signal is processed in the kernel-to-userspace exit codepath. Since the process is deadlocked it won't even make it that far. – bdonlan Mar 25 '12 at 21:14
  • yeah, the signal would be handled only in the kernel-to-userspace exit code path, so we plan to take unconventional mean -- Linux kernel provide a force_sig(), if this function can work in accordance with our expectation(send a signal to a process and wake up it), than we solve it. – silverbullettt Mar 26 '12 at 00:48
  • @silverbullet, no, that won't work. Thread (or process) exit ALWAYS happens from with the kernel thread bound to the thread, precisely to ensure that all locks are released and any datastructures it was manipulating would be left in a clean state. `force_sig` only bypasses userspace signal ignores; it still has to go through all the other normal processing. The only real solution here is to fix the deadlock that's causing the problem in the first place. – bdonlan Mar 26 '12 at 06:06
  • if I send a SIGKILL to a process, and then use wake_up_process() to wake it up immediately, does it work? – silverbullettt Mar 26 '12 at 07:28
  • If it's waiting for a spinlock, it's already awake. If it's waiting for a kernel semaphore or something, it'll go back to sleep immediately. Once you have a deadlock in the kernel, you are doomed. More importantly, that lock was probably protecting something important - if you go and break locks willy-nilly, you'll leave something corrupted, and you'll be in trouble again later. – bdonlan Mar 27 '12 at 05:39