Understanding the Linux kernel for interrupt saving and recovery

Source: Internet
Author: User

In the Linux kernel (linux-4.14.12/mm/slab.c#3389), at first glance at the bottom of the code, it seems that L3389 have a bug, so I read around the interest of a bit local_irq_save/local_irq_ The source code of the restore.

/*linux-4.14.12/mm/slab.c#3389*/3377  Static__always_inlinevoid*3378Slab_alloc (structKmem_cache *cachep, gfp_t flags, unsignedLongcaller)3379  {3380UnsignedLongsave_flags;3381    void*OBJP;3389Local_irq_save (save_flags);3390OBJP =__do_cache_alloc (Cachep, flags);3391Local_irq_restore (save_flags);3399    returnOBJP;3400}

In L3380 and L3389, if Local_irq_save () is a function, there must be a bug, because Save_flags's variable address needs to be passed to Local_irq_save ().

3380      Long save_flags; 3389      Local_irq_save (Save_flags);

However,Local_irq_save () and Local_irq_restore () are not functions, but macros , so there is no bug.

1. Implementation of Local_irq_save () and Local_irq_restore ()

/*linux-4.14.12/include/linux/irqflags.h#139*/ the#ifdef config_trace_irqflags ... the  #defineLocal_irq_save (Flags)111      Do {                                             theRaw_local_irq_save (Flags); 113Trace_hardirqs_off ();  the} while(0) the the117  #defineLocal_irq_restore (Flags)118      Do {                                            119             if(Raw_irqs_disabled_flags (Flags)) { -Raw_local_irq_restore (Flags); 121Trace_hardirqs_off (); 122}Else {                                123trace_hardirqs_on (); 124Raw_local_irq_restore (Flags);  the             }                                       126} while(0)...135  #else/* ! Config_trace_irqflags * *...139  #defineLocal_irq_save (Flags) $      Do {                                                    141Raw_local_irq_save (Flags); 142} while(0)143  #defineLocal_irq_restore (Flags) do {Raw_local_irq_restore (flags),} while (0)...146  #endif/* Config_trace_irqflags */

For the sake of simplicity, we are only concerned! The Config_trace_irqflags branch is just fine,

139  #define Local_irq_save (Flags)                                                                                        , 141              Raw_local_irq_save (flags);                       142      while (0) 143  #define Local_irq_restore (Flags) do {Raw_local_irq_restore (flags),} while (0)

Thus, we can assume that Locale_irq_save ()/local_irq_restore () is equivalent to:

#define Local_irq_save (Flags)    Raw_local_irq_save (flags)#define Local_irq_restore (Flags) RAW _local_irq_restore (Flags)

2. Implementation of Raw_local_irq_save () and Raw_local_irq_restore ()

/*linux-4.14.12/include/linux/irqflags.h#78*/ +  #defineRaw_local_irq_save (Flags) -       Do {                                             theTypecheck (unsignedLong, flags); BayiFlags =Arch_local_irq_save ();  the} while(0) the  #defineRaw_local_irq_restore (Flags) -       Do {                                             -Typecheck (unsignedLong, flags);  theArch_local_irq_restore (Flags);  the} while(0)

About Macro Typecheck () does not explain, because it is very intuitive, is to ensure that the type of flags must be unsigned long. Thus, Raw_local_irq_save () and Raw_local_irq_restore () are equivalent to:

#define Raw_local_irq_save (flags)       flags = Arch_local_irq_save ()#define Raw_local_irq_restore (flags)    Arch_local_irq_restore (Flags)

The following is an example of the implementation of the functions of Arch_local_irq_save () and Arch_local_irq_restore () x86.

3. Arch_local_irq_save () and Arch_local_irq_restore () the implementation of these two functions on the x86

/*linux-4.14.12/arch/x86/include/asm/irqflags.h#70*/ -  StaticInline Notrace unsignedLongArch_local_save_flags (void) in  { the      returnNative_save_fl (); the  } About the  StaticInline NotracevoidArch_local_irq_restore (unsignedLongflags) the  { theNATIVE_RESTORE_FL (flags); +}

Clearly, it's just a matter of understanding the specific implementation of NATIVE_SAVE_FL () and NATIVE_RESTORE_FL ().

Implementation of 3.1 NATIVE_SAVE_FL ()

/*linux-4.14.12/arch/x86/include/asm/irqflags.h#16*/ -  Staticinline unsignedLongNATIVE_SAVE_FL (void) -  { -UnsignedLongflags; + -      /** "=RM" is safe here, because "pops" adjusts the stack Before22 * It evaluates its effective address-- This was part of THE23 * documented behavior of the "Pop" instruction.24*/ -Asmvolatile("# __raw_save_flags\n\t" -                   "PUSHF; pop%0" -:"=rm"(Flags) -:/*No input*/ in:"Memory"); - to      returnflags; +}

This is an inline assembly code, followed by a simple demo to explain.

Implementation of 3.2 NATIVE_RESTORE_FL ()

。。。 Not to be continued ....

Understanding the Linux kernel for interrupt saving and recovery

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.