Find the answer to your Linux question:
Results 1 to 4 of 4
Hi, This is my first post here and hence I am not sure if this is the right place. So if I am totally off coast, please show me the ...
Enjoy an ad free experience by logging in. Not a member yet? Register.
  1. #1
    Just Joined!
    Join Date
    Feb 2008
    Posts
    17

    percpu_irq


    Hi,

    This is my first post here and hence I am not sure if this is the right place. So if I am totally off coast, please show me the right way!

    Ok, here is the deal,
    I am writing a kernel module read the hardware performance counters on the core 2 duo. And I want to enable the register overflow interrupt.
    Got all the hardware stuff done, like setting the interrupt enable bit and things like that, but now I do not know how to associate a handler to it. I googled and found out that the vector is 0xee.

    And from another place that I can use register_percpu_irq.
    But unfortunately later realized that is only for ia64 (As far as I know this is the itanium architecture)

    If someone can help me on this one, I can get out of this little hole and continue.

    Note: I am a newbie with kernel programming, and never dealt with interrupts.... Till NOW.

  2. #2
    Just Joined!
    Join Date
    Apr 2005
    Location
    Romania
    Posts
    42
    Hi,

    First of all, interrupt control methods :

    local_irq_disable() - disable local interrupt delivery

    local_irq_enable() - enable local interrupt delivery

    local_irq_save() - save the current state of local interrupt delivery and then disable it

    local_irq_restore() - restore local interrupt delivery to the given state

    disable_irq() - disable the given interrupt line and ensure no handler on the line is executing before returning

    disable_irq_nosync() - disable the given interrupt line

    enable_irq() - enable the given interrupt line

    irqs_disabled() - returns nonzero if local interrupt delivery is disabled; otherwise returns zero

    in_interrupt() - returns nonzero if in interrupt context and zero if in process context

    in_irq() - returns nonzero if currently executing an interrupt handler and zero otherwise

    So, declaration of an interrupt handler:

    static irqreturn_t intr_handler(int irq, void *dev_id, struct pt_regs *regs)

    The reason the interrupt handler is static is that it's never called directly from another file.

    Drivers can register an interrupt handler and enable a given interrupt line for handling via the function:

    /* request_irq: allocate a given interrupt line */
    int request_irq(unsigned int irq,
    irqreturn_t (*handler)(int, void *, struct pt_regs *),
    unsigned long irqflags,
    const char *devname,
    void *dev_id)

    Unregister a given interrupt handler - if no handlers now exist on the line, the given interrupt line is disabled:

    void free_irq(unsigned int irq, void *dev_id)

    I hope this will help you.

  3. #3
    Just Joined!
    Join Date
    Feb 2008
    Posts
    17

    percpu_irq

    Thanks a lot. I will look into this.

    The problem I was facing was that I do not know the irq no for the interrupt. Only that the local APIC ctrl for the particular interrupt is APIC_LVTPC -> APIC_BASE + 0x340

    I just realized that I can set any vector (not only 0xee) as long as it does not interfere with others and I register it with the local APIC.

    I was looking at patches provided by popular performance counter monitoring software liker perfctr and perfmon and they do everything from within the kernel. (But not by a pluggable module.) using apic_write(APIC_LVTPC, LOCAL_PERF*_VECTOR)

    where LOCAL_PERF*_VECTOR is LOCAL_PERFMON_VECTOR or LOCAL_PERFCTR_VECTOR and both are defined to 0xee and the patch also changes the FIRST_SYSTEM_VECTOR from 0xef to 0xee.
    And then they use BUILD_INTERRUPT(LOCAL_PERF*_INTERRUPT, apic_perf_interrupt) -> in include/asm-x86/mach-default/arch_entry.h
    And then they define a fucntion:
    fastcall smp_apic_perf_interrupt(<forgot> *regs){
    IRQ_Ack();
    IRQ_enter();
    /* Do whatever */
    IRQ_exit()
    }

    Now from your post and what I have observed from these patches, I am extremely confused. I am now aware of the complexity and power of the APIC architecture on x86 and the beauty of the linux kernel in handling these things!

    I have read the interrupts section from the following books:
    Linux device drivers
    Understanding the linux kernel
    Linux kernel Development
    Linux kernel primer

    But I am missing 1 basic understanding. What is the IRQ parameter? Is it related to 1 line to the IO APIC or the Local APIC? And the NR_IRQS is arount 238 (I do not remember the exact number from a test module which just printed that value from the init function) and not 256. Why is this?

    Please do not judge me based on my naivete!

  4. #4
    Just Joined!
    Join Date
    Feb 2008
    Posts
    17
    Hi, Thanks, I figured it out. What I had done, worked. I realized that when I put in printk's Thanks a lot, I will definitely return the favor by helping those I can help. The true GNU way!

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •