Перехватчики обработчика kretprobe показывают ОШИБКУ: планирование в атомарном режимеLinux

Ответить Пред. темаСлед. тема
Anonymous
 Перехватчики обработчика kretprobe показывают ОШИБКУ: планирование в атомарном режиме

Сообщение Anonymous »

Я пытался использовать kretprobe, чтобы перехватить системный вызов umount с помощью обработчика сообщений в моем модуле ядра.

Код: Выделить всё

static struct kretprobe umount_kretprobe = {
.entry_handler  = umount_kprobe_pre_handler,
.handler        = umount_kprobe_post_handler,
.kp.symbol_name = "__x64_sys_umount",
.data_size      = sizeof(struct umount_data),
// /* Probe up to 20 instances concurrently. */
.maxactive      = 20,
};
В обработчике сообщения (

Код: Выделить всё

umount_kprobe_post_handler
), мы обнаружили, что в некоторых сценариях, когда мы находимся в перехваченном обработчике сообщений, операция umount не синхронизировалась ОС. Однако я хочу гарантировать, что возвращаемое значение системного вызова umount будет в обработчике сообщения, поэтому нам нужно сначала сбросить его.
Использованная мной функция сброса выглядела следующим образом:

Код: Выделить всё

void flush_tasks(){
struct task_struct *task = current;
struct callback_head *work, *head, *next;

for (;;) {
do {
work = ACCESS_ONCE(task->task_works);
head = NULL; // current should not be PF_EXITING
} while (cmpxchg(&task->task_works, work, head) != work);

if (!work)
break;

raw_spin_lock_irq(&task->pi_lock);
raw_spin_unlock_irq(&task->pi_lock);

head = NULL;
do {
next = work->next;
work->next = head;
head = work;
work = next;
} while (work);

work = head;
do {
next = work->next;
work->func(work);
work = next;
cond_resched();
} while (work);
}
}
После того, как мы вызвали эту функцию в umount_kprobe_post_handler, возникла ошибка ядра «ОШИБКА: атомарное планирование».
Стек вызовов показал:

Код: Выделить всё

[Mon Jul  1 06:23:07 2024] BUG: scheduling while atomic: umount/3090/0x00000002
[Mon Jul  1 06:23:07 2024] Modules linked in:  nft_fib_inet nft_fib_ipv4 nft_fib_ipv6 nft_fib nft_reject_inet nf_reject_ipv4 nf_reject_ipv6 nft_reject nft_ct nft_chain_nat nf_nat nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 rfkill ip_set nf_tables qrtr intel_rapl_msr intel_rapl_common intel_uncore_frequency_common isst_if_mbox_msr sunrpc isst_if_common nfit libnvdimm rapl raid1 dm_raid i2c_piix4 virtio_balloon raid456 async_raid6_recov async_memcpy async_pq pktcdvd async_xor async_tx joydev fuse loop dm_multipath nfnetlink zram xfs crct10dif_pclmul crc32_pclmul crc32c_intel polyval_clmulni polyval_generic ghash_clmulni_intel sha512_ssse3 sha256_ssse3 virtio_scsi sha1_ssse3 virtio_net net_failover bochs drm_vram_helper drm_ttm_helper ttm failover qemu_fw_cfg serio_raw ata_generic pata_acpi scsi_dh_rdac scsi_dh_emc scsi_dh_alua virtio_console
[Mon Jul  1 06:23:07 2024] CPU: 1 PID: 3090 Comm: umount Tainted: G           OE     -------  ---  6.8.0-0.rc6.49.fc40.x86_64 #1
[Mon Jul  1 06:23:07 2024] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Virtualization-2.5.1-11303-200428-0-gfff70e7 04/01/2014
[Mon Jul  1 06:23:07 2024] Call Trace:
[Mon Jul  1 06:23:07 2024]  
[Mon Jul  1 06:23:07 2024]  dump_stack_lvl+0x4d/0x70
[Mon Jul  1 06:23:07 2024]  __schedule_bug+0x56/0x70
[Mon Jul  1 06:23:07 2024]  __schedule+0x10a7/0x1530
[Mon Jul  1 06:23:07 2024]  ? mod_delayed_work_on+0x66/0xb0
[Mon Jul  1 06:23:07 2024]  ? wb_queue_work+0x8e/0x100
[Mon Jul  1 06:23:07 2024]  schedule+0x32/0xd0
[Mon Jul  1 06:23:07 2024]  wb_wait_for_completion+0x89/0xc0
[Mon Jul  1 06:23:07 2024]  ? __pfx_autoremove_wake_function+0x10/0x10
[Mon Jul  1 06:23:07 2024]  __writeback_inodes_sb_nr+0xa4/0xd0
[Mon Jul  1 06:23:07 2024]  sync_filesystem+0x31/0xa0
[Mon Jul  1 06:23:07 2024]  generic_shutdown_super+0x26/0x110
[Mon Jul  1 06:23:07 2024]  kill_block_super+0x1a/0x40
[Mon Jul  1 06:23:07 2024]  ext4_kill_sb+0x22/0x40
[Mon Jul  1 06:23:07 2024]  deactivate_locked_super+0x30/0xb0
[Mon Jul  1 06:23:07 2024]  cleanup_mnt+0xba/0x150
[Mon Jul  1 06:23:07 2024]  flush_tasks+0x7c/0xa0 [my_module]
Я предполагаю, что основная причина этой ошибки заключается в том, что обработчики kretprobe были спроектированы как атомарные, поэтому мы не можем запустить планирование в обработчиках pre/post его перехватчика. Я прав?
Может ли кто-нибудь предложить обходной путь? Я хочу перехватить системный вызов umount с помощью обработчика сообщений, и мне нужно убедиться, что размонтирование точно завершено операционной системой.

Подробнее здесь: https://stackoverflow.com/questions/787 ... ile-atomic
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение
  • Обработчики kretprobe в ядре 3.x не вызываются
    Anonymous » » в форуме Linux
    0 Ответы
    16 Просмотры
    Последнее сообщение Anonymous
  • Обработчики kretprobe в ядре 3.x не вызываются
    Anonymous » » в форуме Linux
    0 Ответы
    19 Просмотры
    Последнее сообщение Anonymous
  • Почему добавление обработчика событий во время обработчика, кажется, работает иначе, от его удаления?
    Anonymous » » в форуме Javascript
    0 Ответы
    6 Просмотры
    Последнее сообщение Anonymous
  • Как получить веб-перехватчики уведомлений Facebook в PHP?
    Гость » » в форуме Php
    0 Ответы
    56 Просмотры
    Последнее сообщение Гость
  • Остановить перехватчики, которые не срабатывают в LLDB (iOS)
    Anonymous » » в форуме IOS
    0 Ответы
    21 Просмотры
    Последнее сообщение Anonymous

Вернуться в «Linux»