Details
-
Bug
-
Resolution: Unresolved
-
Minor
-
None
-
None
-
None
-
3
-
9223372036854775807
Description
dma_[un]map_sgtable() wants all orig_nents segments to be populated, but we may only populate a subset of them. To work around this we overwrite orig_nents with the number of actually populated segments:
static int kfilnd_tn_set_sgl_buf(struct lnet_ni *ni,
struct kfilnd_transaction *tn,
struct bio_vec *kiov, int num_iov, int offset,
int nob)
{
...
sg = tn->tn_sgt.sgl;
do {
LASSERT(num_iov > 0);
if (!sg) {
CERROR("%s: lacking enough sg entries to map tx: rc = %d\n",
ni->ni_interface, -EFAULT);
sg_free_table(&tn->tn_sgt);
return -EFAULT;
}
sg_count++;
fragnob = min_t(int, (kiov->bv_len - offset), nob);
sg_set_page(sg, kiov->bv_page, fragnob,
kiov->bv_offset + offset);
sg = sg_next(sg);
offset = 0;
kiov++;
num_iov--;
nob -= fragnob;
} while (nob > 0);
tn->tn_dmadir = tn->sink_buffer ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
tn->tn_sgt.orig_nents = sg_count; <<<<<<<<<<<<
However, orig_nents is supposed to remain the original allocation size so that sg_free_table() can decide whether it must dismantle a chained multi-page table or just issue kfree(). Thus we can hit the following error:
[Tue Nov 4 10:38:45 2025] WARNING: CPU: 1 PID: 806 at mm/slub.c:3591 free_nonslab_page+0x70/0x90 [Tue Nov 4 10:38:45 2025] CPU: 1 PID: 806 Comm: kworker/1:1H Kdump: loaded Tainted: G OE -------- - - 4.18.0-553.36.1.el8_10.x86_64 #1 [Tue Nov 4 10:38:45 2025] Hardware name: Viking Enterprise Solutions VSSEP1EA/VSSEP1EA, BIOS 10.10.02 11/04/2020 [Tue Nov 4 10:38:45 2025] Workqueue: kfilnd_wq kfilnd_cq_process_completion [kkfilnd] [Tue Nov 4 10:38:45 2025] RIP: 0010:free_nonslab_page+0x70/0x90 [Tue Nov 4 10:38:45 2025] Code: be 06 00 00 00 48 89 df e8 0d 10 02 00 48 89 ef 57 9d 0f 1f 44 00 00 48 83 c4 08 44 89 e6 48 89 df 5b 5d 41 5c e9 10 5b fd ff <0f> 0b 80 3d 8d 0f c4 01 00 75 ba e9 a8 76 00 00 ba 00 f0 ff ff 45 [Tue Nov 4 10:38:45 2025] RSP: 0018:ffffb4dc8e807c48 EFLAGS: 00010246 [Tue Nov 4 10:38:45 2025] RAX: dead000000000100 RBX: ffffe1f2c41f1240 RCX: ffffffffb74e7a10 [Tue Nov 4 10:38:45 2025] RDX: 00000000fffff000 RSI: ffff94c507c49000 RDI: ffffe1f2c41f1240 [Tue Nov 4 10:38:45 2025] RBP: ffffe1f2c41f1240 R08: 0000000000000001 R09: 0000000000000000 [Tue Nov 4 10:38:45 2025] R10: ffff94c581a6b000 R11: ffff94c581a6a354 R12: 0000000000000000 [Tue Nov 4 10:38:45 2025] R13: ffff94c507c49000 R14: ffffffffb74e7a10 R15: 0000000000000002 [Tue Nov 4 10:38:45 2025] FS: 0000000000000000(0000) GS:ffff94d42fa40000(0000) knlGS:0000000000000000 [Tue Nov 4 10:38:45 2025] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [Tue Nov 4 10:38:45 2025] CR2: 00007f7576a17000 CR3: 000000010875a000 CR4: 0000000000350ee0 [Tue Nov 4 10:38:45 2025] Call Trace: [Tue Nov 4 10:38:45 2025] ? __warn+0x94/0xe0 [Tue Nov 4 10:38:45 2025] ? free_nonslab_page+0x70/0x90 [Tue Nov 4 10:38:45 2025] ? free_nonslab_page+0x70/0x90 [Tue Nov 4 10:38:45 2025] ? report_bug+0xb1/0xe0 [Tue Nov 4 10:38:45 2025] ? do_error_trap+0x9e/0xd0 [Tue Nov 4 10:38:45 2025] ? do_invalid_op+0x36/0x40 [Tue Nov 4 10:38:45 2025] ? free_nonslab_page+0x70/0x90 [Tue Nov 4 10:38:45 2025] ? invalid_op+0x14/0x20 [Tue Nov 4 10:38:45 2025] ? sg_miter_start+0x60/0x60 [Tue Nov 4 10:38:45 2025] ? sg_miter_start+0x60/0x60 [Tue Nov 4 10:38:45 2025] ? free_nonslab_page+0x70/0x90 [Tue Nov 4 10:38:45 2025] ? __sg_free_table+0x5f/0x80 [Tue Nov 4 10:38:45 2025] kfree+0x20e/0x250 [Tue Nov 4 10:38:45 2025] ? sg_miter_start+0x60/0x60 [Tue Nov 4 10:38:45 2025] __sg_free_table+0x5f/0x80 [Tue Nov 4 10:38:45 2025] kfilnd_tn_free+0x23a/0x3a0 [kkfilnd] [Tue Nov 4 10:38:45 2025] kfilnd_tn_state_wait_tag_rma_comp+0x1d0/0x5d0 [kkfilnd] [Tue Nov 4 10:38:45 2025] kfilnd_tn_event_handler+0x5a/0xb0 [kkfilnd] [Tue Nov 4 10:38:45 2025] kfilnd_cq_process_completion+0xa2/0x260 [kkfilnd] [Tue Nov 4 10:38:45 2025] ? srso_return_thunk+0x5/0x5f [Tue Nov 4 10:38:45 2025] ? __switch_to+0x10c/0x430 [Tue Nov 4 10:38:45 2025] ? srso_return_thunk+0x5/0x5f [Tue Nov 4 10:38:45 2025] process_one_work+0x1d3/0x390 [Tue Nov 4 10:38:45 2025] ? process_one_work+0x390/0x390 [Tue Nov 4 10:38:45 2025] worker_thread+0x30/0x390 [Tue Nov 4 10:38:45 2025] ? process_one_work+0x390/0x390 [Tue Nov 4 10:38:45 2025] kthread+0x134/0x150 [Tue Nov 4 10:38:45 2025] ? set_kthread_struct+0x50/0x50 [Tue Nov 4 10:38:45 2025] ret_from_fork+0x35/0x40 [Tue Nov 4 10:38:45 2025] ---[ end trace c1fc7cb5ec4096d2 ]--- [Tue Nov 4 10:38:45 2025] object pointer: 0x000000004f957af0
Fix is to save the original allocation size and restore it prior to free'ing the sg_table.