Question about using spinlock to synchronize between kernel driver and an interrupt handler

Pranay Srivastava pranjas at gmail.com
Sat Feb 1 08:39:43 EST 2014


On Feb 1, 2014 2:48 PM, "m silverstri" <michael.j.silverstri at gmail.com>
wrote:
>
> By driver code , I mean the code which set the register values and
> wait till the values is set (via an interrupt handler) before
> continues doing something else
>
>
> On Sat, Feb 1, 2014 at 1:06 AM, anish singh <anish198519851985 at gmail.com>
wrote:
> > On Sat, Feb 1, 2014 at 1:03 AM, m silverstri
> > <michael.j.silverstri at gmail.com> wrote:
> >> On Sat, Feb 1, 2014 at 12:48 AM, anish singh
> >> <anish198519851985 at gmail.com> wrote:
> >>> On Sat, Feb 1, 2014 at 12:32 AM, m silverstri
> >>> <michael.j.silverstri at gmail.com> wrote:
> >>> don't top-post
> >>>
> >>>> In my driver code,
> >>>> I want to set a bit in a  HW Register 1. HW will send an interrupt
> >>> Yes this is how most drivers work.
> >>>
> >>>> when setting the register is done.
> >>>> I don't want my driver code to block until the interrupt is sent
from the HW.
> >>> so i suppose this is what you want to do.
> >>>
> >>>
> >>> write ->register->interrupt happens->disable register ->handle
interrupt
> >>> --->enable register.
> >>> Look at any driver code from linux kernel code and it mostly does
this.
> >>>>
> >>
> >> Thanks.
> >> But I want my driver code to block until I get the interrupt from HW.
> >
> > if (driver code == interrupt handler) {
> >    it_is_not_running_anyway_as_there_is_no_interrupt
> > } else {
> >    i don't know what you mean by driver code here?
> > }
> >>
> >>
> >>
> >>>>
> >>>>
> >>>> On Sat, Feb 1, 2014 at 12:06 AM, anish singh
> >>>> <anish198519851985 at gmail.com> wrote:
> >>>>> On Fri, Jan 31, 2014 at 11:55 PM, m silverstri
> >>>>> <michael.j.silverstri at gmail.com> wrote:
> >>>>>> Hi,
> >>>>>>
> >>>>>> I read this article http://www.linuxjournal.com/article/5833 to
learn
> >>>>>> about spinlock. I try this to use it in my kernel driver.
> >>>>>>
> >>>>>> Here is what my driver code needs to do:
> >>>>>> In f1(), it will get the spin lock, and caller can call f2() will
wait
> >>>>>> for the lock since the spin lock is not being unlock. The spin lock
> >>>>>> will be unlock in my interrupt handler (triggered by the HW).
> >>>>> Wrong design!!!
> >>>>>>
> >>>>>> void f1() {
> >>>>>> spin_lock(&mylock);
> >>>>>> // write hardware
> >>>>>> REG_ADDR += FLAG_A;
> >>>>> So here you take spinlock and release in interrupt handler.What
> >>>>> if there is no interrupt handler and someone calls this fucntion
> >>>>> he will blocked forever.
> >>>>>>
> >>>>>> }
> >>>>>>
> >>>>>> void f2() {
> >>>>>> spin_lock(&mylock);
> >>>>>> //...
> >>>>>> }
> >>>>>>
> >>>>>> The hardware will send the application an interrupt and my
interrupt
> >>>>>> handler will call spin_unlock(&mylock);
> >>>>>>
> >>>>>> My question is if I call
> >>>>>> f1()
> >>>>>> f2() // i want this to block until the interrupt return saying
settingyou

I think you want to block a task for an event to happen. That event is
triggered by HW.

What i would suggest is that you use completion variable which would be per
request. Don't make it global otherwise you'll again need locks to protect
global variable. Try to pass this completion variable along with request to
your driver.

Also i suppose that your driver could implement a list where requests from
tasks can be queued and each task would wait for completion which already
is per task embedded in its request.

The driver would deque requests one by one or depending on how many
requests can your hw handle and will trigger completion waking up the task
that triggered it.

So you'll have a clean api design where locks are held and unlocked at same
layer instead of current design.

> >>>>>> REG_ADDR is done.
> >>>>>>
> >>>>>> when I run this, I get an exception in kernel saying a deadlock "
> >>>>>> INFO: possible recursive locking detected"
> >>>>>>
> >>>>>> How  can I re-write my code so that kernel does not think I have a
deadlock?
> >>>>>>
> >>>>>> I want my driver code to wait until HW sends me an interrupt saying
> >>>>>> setting REG_ADDR is done.
> >>>>> Let us know what is your requirement?I am sure there must be a
simple
> >>>>> way to handle than this magic done here.
> >>>>> Explain what are you trying to do in detail and I am sure lot of
> >>>>> people will jump
> >>>>> to help.
> >>>>>>
> >>>>>> Thank you.
> >>>>>>
> >>>>>> _______________________________________________
> >>>>>> Kernelnewbies mailing list
> >>>>>> Kernelnewbies at kernelnewbies.org
> >>>>>> http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
>
> _______________________________________________
> Kernelnewbies mailing list
> Kernelnewbies at kernelnewbies.org
> http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies

    ---P.K.S
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.kernelnewbies.org/pipermail/kernelnewbies/attachments/20140201/bac8c5d0/attachment.html 


More information about the Kernelnewbies mailing list