lkml.org 
[lkml]   [2023]   [Jan]   [31]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
Date
SubjectRe: [PATCH 1/5] genirq: Use hlist for managing resend handlers
From


On 1/31/23 10:17, Shanker Donthineni wrote:
>
>
> On 1/31/23 02:59, Thomas Gleixner wrote:
>> On Sun, Jan 29 2023 at 18:57, Shanker Donthineni wrote:
>>> +/* hlist_head to handle software resend of interrupts: */
>>> +static HLIST_HEAD(irq_resend_list);
>>> +static DEFINE_RAW_SPINLOCK(irq_resend_lock);
>>>
>>>   /*
>>>    * Run software resends of IRQ's
>>> @@ -30,18 +31,16 @@ static DECLARE_BITMAP(irqs_resend, IRQ_BITMAP_BITS);
>>>   static void resend_irqs(struct tasklet_struct *unused)
>>>   {
>>>        struct irq_desc *desc;
>>> -     int irq;
>>> -
>>> -     while (!bitmap_empty(irqs_resend, nr_irqs)) {
>>> -             irq = find_first_bit(irqs_resend, nr_irqs);
>>> -             clear_bit(irq, irqs_resend);
>>> -             desc = irq_to_desc(irq);
>>> -             if (!desc)
>>> -                     continue;
>>> +     struct hlist_node *n;
>>> +
>>> +     raw_spin_lock_irq(&irq_resend_lock);
>>> +     hlist_for_each_entry_safe(desc, n, &irq_resend_list, resend_node) {
>>> +             hlist_del_init(&desc->resend_node);
>>>                local_irq_disable();
>>>                desc->handle_irq(desc);
>>>                local_irq_enable();
>>>        }
>>> +     raw_spin_unlock_irq(&irq_resend_lock);
>> The lock ordering is broken here. irq_sw_resend() is invoked with
>> desc->lock held and takes irq_resend_lock.
>>
>> Lockdep clearly would have told you...
>>
>>          raw_spin_lock_irq(&irq_resend_lock);
>>          while (!hlist_empty(...)) {
>>                  desc = hlist_entry(irq_resend_list.first, ...);
>>                  hlist_del_init(&desc->resend_node);
>>                  raw_spin_unlock(&...);
>>                  desc->handle_irq();
>>                  raw_spin_lock(&...);
>>          }
>
> Thanks for catching mistakes, I'll change it to this, please correct me if
> I'm doing another mistake.
>
> static void resend_irqs(struct tasklet_struct *unused)
> {
>         struct irq_desc *desc;
>
>         raw_spin_lock_irq(&irq_resend_lock);
>         while (hlist_empty(&irq_resend_list)) {

Sorry typo "while (!hlist_empty(&irq_resend_list)) {"


>                 desc = hlist_entry(irq_resend_list.first, struct irq_desc,
>                                    resend_node);
>                 hlist_del_init(&desc->resend_node);
>                 raw_spin_unlock(&irq_resend_lock);
>                 desc->handle_irq(desc);
>                 raw_spin_lock(&irq_resend_lock);
>         }
>         raw_spin_unlock_irq(&irq_resend_lock);
> }
>
> Thanks,
> Shanker

\
 
 \ /
  Last update: 2023-03-27 00:04    [W:0.077 / U:19.544 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site