Subject: Re: Multiple Processor support and LKM's
To: None <netbsd-users@netbsd.org>
From: Ian McIntosh <ianm@cat.co.za>
List: netbsd-users
Date: 07/27/2007 17:46:36
Christos Zoulas wrote:
> In article <46A8BCB3.3060203@cat.co.za>, Ian McIntosh  <ianm@cat.co.za> wrote:
>   
>> Christos Zoulas wrote:
>>     
>>> Yes, compiling with MULTIPROCESSOR should work. Are your kernels compiled
>>> with LOCKDEBUG or other options that might change the size of structures?
>>>
>>> christos
>>>
>>>   
>>>       
>> Thanks for the help, I cleaned my kernel and carefully config'ed it 
>> again without LOCKDEBUG or any other options that change the structures 
>> (as far as I can see). With this kernel I get somewhat better behaviour 
>> in that PCI reads seem to work correctly. The problem now, is that once 
>> the lkm loads it doesn't get any interrupts. A look at dmesg indicates 
>> that my driver has been assigned ioapic0 pin 11 as its interrupt pin but 
>> vmstat indicates there are no interrupts being generated for this pin.
>> However the interrupt counts for ioapic0 pin 17 seem to be going wild. A 
>> top on the system indicates that CPU0 is 72% idle when it was 100% idle 
>> before the lkm loaded. Looking at /var/log/messages ioapic0 pin 17 is 
>> assigned to uhci1 (USB controller I think).  Below is the vmstat before 
>> and after the lkm load and the relevant dmesg.
>>
>>
>> I would really appreciate any pointers here...
>>
>>     
>
> I don't remember the API for 3.x, but under current you need to both
> map and establish the interrupt...
>
> christos
>
>   
As far as I can see, for 3.x you have to do the same, I attach the code 
fragment used below. I assume that if the interrupt mapping (and 
establishing) was incorrect, the lkm would not function in a single 
processor kernel either. In this case the lkm works perfectly for the 
single processor kernel but with GENERIC.MPACPI it doesn't. Is there 
anything else I can check to shed some more light?

Ian

  //  Set up interrupt handler.
    if (pci_intr_map(pap,&intrhandle) != 0)
    {
      printf(": couldn't map PCI interrupt\n");
      return;
    }

  intrstr = pci_intr_string(pap->pa_pc, intrhandle);

  // choose TTY interrupt level
  sc->sc_ih = pci_intr_establish(pap->pa_pc, intrhandle, 
IPL_TTY,mov_intr, sc);
  if(sc->sc_ih == NULL)
    {
      printf(": couldn't establish interrupt");
      if(intrstr != NULL)
        printf(" at %s", intrstr);
      printf("\n");
      return;
    }
 
  if(intrstr != NULL)
    printf("\r\n: intrstr %s dv_xname %s", intrstr, self->dv_xname);