Linux tasklet - interrupt mode

收錄在 Ameba 的 100 篇

--

繼前篇: cortex M NVIC / RTOS and Linux tasklet / work queue


如何確定 tasklet 因為用 softirq 機制, 而處在 interrupt mode 呢,

對此, kernel 在 include/linux/preempt.h 有提供:
in_interrupt(), 來確定是否是在 interrupt mode 下.


在註解中有描述, 只要是在 NMI / IRQ / SoftIRQ 或 BH disabled 時, 值就不是 0
實際測試一下:

https://github.com/neojou/new_ldd/blob/master/tasklet_schedule/tasklet_schedule.c


執行結果:

module init : in_interrupt(): 0x0
tasklet_handler work
tasklet: in_interrupt(): 0x100
tasklet: in_irq(): 0x0
tasklet: in_softirq(): 0x100
tasklet: in_nmi(): 0x0

可以發現 softirq bit 被舉起來了, 表示在 interrupt mode,
而 module init 時, 是在一般 process mode.



進一步如前篇所述, 如果我們在 tasklet 中 sleep 會發生甚麼事呢?
我們加一行 msleep(20); 看看

可以發現, 會出現: BUG: scheduling while atomic: ksoftirqd
從 call trace 也可以看出, tasklet 是從 __do_softirq() 啟動的

[24475.199236] BUG: scheduling while atomic: ksoftirqd/1/16/0x00000100
[24475.200001] Modules linked in: tasklet_schedule(OE) ipheth rfcomm bnep binfmt_misc uvcvideo intel_rapl_msr intel_rapl_common videobuf2_vmalloc videobuf2_memops x86_pkg_temp_thermal intel_powerclamp videobuf2_v4l2 coretemp videobuf2_common videodev kvm_intel mc kvm snd_hda_codec_realtek irqbypass iwlmvm snd_hda_codec_hdmi snd_hda_codec_generic mac80211 snd_hda_intel dell_laptop snd_hda_codec crct10dif_pclmul crc32_pclmul libarc4 ghash_clmulni_intel aesni_intel snd_hda_core aes_x86_64 crypto_simd ledtrig_audio snd_hwdep cryptd glue_helper intel_cstate dell_smm_hwmon intel_rapl_perf snd_pcm snd_seq_midi snd_seq_midi_event snd_rawmidi snd_seq dell_wmi joydev input_leds serio_raw dell_smbios snd_seq_device sparse_keymap snd_timer snd dcdbas wmi_bmof dell_wmi_descriptor btusb btrtl soundcore iwlwifi btbcm btintel bluetooth cfg80211 ecdh_generic ecc acpi_pad mei_me lpc_ich mac_hid dell_rbtn mei parport_pc ppdev lp parport autofs4 nouveau i915 ttm i2c_algo_bit drm_kms_helper syscopyarea
[24475.200023]  sysfillrect sysimgblt fb_sys_fops mxm_wmi psmouse ahci drm libahci r8169 realtek wmi i2c_hid video hid [last unloaded: tasklet_schedule]
[24475.200029] CPU: 1 PID: 16 Comm: ksoftirqd/1 Tainted: G           OE     5.3.1 #1
[24475.200029] Hardware name: Dell Inc. Inspiron 5558/0WMF3P, BIOS A02 03/09/2015
[24475.200030] Call Trace:
[24475.200036]  dump_stack+0x5c/0x7b
[24475.200039]  __schedule_bug+0x51/0x70
[24475.200041]  __schedule+0x558/0x670
[24475.200042]  ? sort_range+0x20/0x20
[24475.200043]  schedule+0x2f/0xa0
[24475.200044]  schedule_timeout+0x164/0x300
[24475.200046]  ? sort_range+0x20/0x20
[24475.200048]  ? __next_timer_interrupt+0xc0/0xc0
[24475.200050]  msleep+0x29/0x30
[24475.200052]  tasklet_action_common.isra.22+0x5e/0x110
[24475.200054]  __do_softirq+0xe3/0x2dc
[24475.200056]  ? sort_range+0x20/0x20
[24475.200057]  run_ksoftirqd+0x26/0x40
[24475.200058]  smpboot_thread_fn+0xef/0x160
[24475.200060]  kthread+0x113/0x130
[24475.200062]  ? kthread_park+0xa0/0xa0
[24475.200063]  ret_from_fork+0x35/0x40
[24475.222070] softirq: huh, entered softirq 6 TASKLET 000000004c2ec23f with preempt_count 00000100, exited with 00000000?

留言

熱門文章