在Linux内核中(linux-4.14.12/mm/slab.c#3389), 乍一看下边的代码,貌似L3389有bug,于是我就绕偶兴趣地阅读了一下local_irq_save/local_irq_restore的源代码。
/*linux-4.14.12/mm/slab.c#3389*/
3377 static __always_inline void *
3378 slab_alloc(struct kmem_cache *cachep, gfp_t flags, unsigned longcaller)3379{3380 unsigned longsave_flags;3381 void *objp;
....3389local_irq_save(save_flags);3390 objp =__do_cache_alloc(cachep, flags);3391local_irq_restore(save_flags);
....3399 returnobjp;3400 }
在L3380和L3389中, 如果local_irq_save()是一个函数,必然存在着bug, 因为需要把save_flags的变量地址传给local_irq_save()才对。
3380 unsigned longsave_flags;
....3389 local_irq_save(save_flags);
但是,local_irq_save()和local_irq_restore()不是函数,而是宏,这样就没有bug了。
1. local_irq_save()和local_irq_restore()的实现
/*linux-4.14.12/include/linux/irqflags.h#139*/
105#ifdef CONFIG_TRACE_IRQFLAGS
...110 #define