Re: Usage of Semaphore with a workqueue

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Michael,

Nice to discuss with you.

On Thu, Apr 2, 2009 at 1:55 PM, Michael Blizek
<michi1@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx> wrote:
> Hi!
>
> On 08:06 Thu 02 Apr     , Peter Teoh wrote:
>> i think u are right, looking at drivers/char/rocket.c as an example
>> (read the comment):
>>
>> /*
>>  *  Exception handler - write routine, called when user app writes to
>> the device.
>>  *  A per port write mutex is used to protect from another process writing to
>>  *  this port at the same time.  This other process could be running
>> on the other CPU
>>  *  or get control of the CPU if the copy_from_user() blocks due to a
>> page fault (swapped out).
>>  *  Spinlocks protect the info xmit members.
>>  */
>> static int rp_write(struct tty_struct *tty,
>>                     const unsigned char *buf, int count)
>> {
>>         struct r_port *info = tty->driver_data;
>>         CHANNEL_t *cp;
>>         const unsigned char *b;
>>         int c, retval = 0;
>>         unsigned long flags;
>>
>>         if (count <= 0 || rocket_paranoia_check(info, "rp_write"))
>>                 return 0;
>>
>>         if (mutex_lock_interruptible(&info->write_mtx))
>>                 return -ERESTARTSYS;
>
> What makes you think that this is called in workqueue context? The only
> caller of this function I have found is in drivers/char/rocket.c
> "static const struct tty_operations rocket_ops". It is probably called
> in system call context. For this reason, the mutex is locked interruptible

The concern is not workqueue vs no workqueue context.   It is
sleepable vs non-sleepable context.   rp_write() is called in
tty_operations's write() API, so if rp_put_char() can sleep (which is
tty's put_char() API), i don't see why rp_write() cannot sleep).   So
mutex_lock() could have been used, but then this could wait forever
(which is the case for rp_put_char()), so it is better to return an
error condition.

Anyway, this is an example of interrupt sending work to be done to
another non-interrupt context (sleepable).

If u want exact identical example of interrupt sending work to a
workqueue (which is also sleepable) I found this
drivers/memstick/core/memstick.c.  except that it is not ERESTARTSYS,
but EAGAIN, which I think should be more appropriate for a harmless
device :-).   (ERESTARTSYS and EINTR sometimes is intermixable????,
tell me more :-))

> and the return value is ERESTARTSYS. This value is not returned, if the
> mutex is locked, but if the mutex is locked and the user space process
> receives a signal. In this case the system call has to terminate, because
> otherwise the call of the user space signal handler will be delayed. The
> system call will be restarted be the user space application, which gets
> errno set to EINTR by write().
>




-- 
Regards,
Peter Teoh

--
To unsubscribe from this list: send an email with
"unsubscribe kernelnewbies" to ecartis@xxxxxxxxxxxx
Please read the FAQ at http://kernelnewbies.org/FAQ



[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux