Ingo Weinhold wrote: > > On 2008-10-29 at 23:23:33 [+0100], François Revol <revol@xxxxxxx> wrote: > > > > > > could someone help me with an acquire_sem_etc() problem? I am unsure > > > about > > > the B_CAN_INTERRUPT flag and handling B_INTERRUPTED as the error code. > > > > userland acquires are always interruptible. > > Usually you don't want to be interruptible when you implement locking > > primitives, to avoid screwing up the state. > > > > > When exactly do I want acquire_sem_etc() to be interruptable, and who > > > can > > > interrupt me? > > > > For things like read() hooks in drivers, when waiting for a buffer, > > it's desirable to be interruptible, so someone can actually hit CTRL-C > > in a terminal and get the desired behaviour. > > In general I think anything that waits for an event with a long timeout > > should be interruptible. > > > > Anyone who can send unmasked signals to the current thread can > > interrupt. > > The suspend_thread() + resume_thread() combo does also interrupt, so does > debug_thread(). There might be other situations -- grep through the > kernel code for thread_interrupt(), if you're interested. > > > Sometimes, even in locking primitives, it's done as while > > (acquire_sem_etc(s, B_CAN_INTERRUPT, ...) == B_INTERRUPTED); > > > > This might be to eat signals and avoid delaying them instead, though > > I'm not sure. > > I've seen that in the NFS addon code for ex. > > It can't be to let the thread handle the signal, as it won't be done > > until it actually exit from the syscall... > > If that is done in kernel code, it's buggy. Signals are only handled > right before leaving the kernel, that is this would become a busy loop. > > > > As for the specific problem I am trying to fix: In the usb_hid driver, > > > Michael and I use a USB interrupt transfer callback semaphore. In > > > other > > > words, the thread that does ioctl() on the driver schedules an USB > > > interrupt transfer, then it blocks on a semaphore which has been > > > created > > > like this: > > If this is guaranteed to be done in a short time (I'm talking ms here), > the acquire_sem_etc() probably doesn't need to be interruptable. If it > can potentially take a long time (even if that's only in cases of > hardware errors or the like), it really should be interruptable and the > ioctl() should return immediately when that happens. One potential > problem is that there's probably some kind of cleanup needed in such a > case. Also the operation might still be performed successfully after all, > so the caller might thus get out of sync with its view of the device. > > A kind of middle-ground is the flag B_KILL_CAN_INTERRUPT. It works like > B_CAN_INTERRUPT, iff the thread has received a kill signal. I.e. neither > SIGWINCH or Ctrl-C wouldn't interrupt it, but "kill -9" or > ProcessController Kill would. That doesn't change the need for cleanup > (if any), but at least one doesn't need to worry about the caller getting > a wrong picture of the situation, since it will never see userland again. > > BTW, if you make the ioctl() interruptable you might want to consider > making it automatically restartable. Ok, am I summing up correctly that I do want to use B_CAN_INTERRUPT, but then if I get B_INTERRUPTED as the return code from acquire_sem_etc() -> treat that as error and bail out. In another words, I wouldn't get interrupted unintentionally by "something unrelated", would I? Best regards, -Stephan