Skip to content

Commit 5e901d0

Browse files
Arun Easimartinkpetersen
Arun Easi
authored andcommitted
scsi: qedi: Fix bad pte call trace when iscsiuio is stopped.
munmap done by iscsiuio during a stop of the service triggers a "bad pte" warning sometimes. munmap kernel path goes through the mmapped pages and has a validation check for mapcount (in struct page) to be zero or above. kzalloc, which we had used to allocate udev->ctrl, uses slab allocations, which re-uses mapcount (union) for other purposes that can make the mapcount look negative. Avoid all these trouble by invoking one of the __get_free_pages wrappers to be used instead of kzalloc for udev->ctrl. BUG: Bad page map in process iscsiuio pte:80000000aa624067 pmd:3e6777067 page:ffffea0002a98900 count:2 mapcount:-2143289280 mapping: (null) index:0xffff8800aa624e00 page flags: 0x10075d00000090(dirty|slab) page dumped because: bad pte addr:00007fcba70a3000 vm_flags:0c0400fb anon_vma: (null) mapping:ffff8803edf66e90 index:0 Call Trace: dump_stack+0x19/0x1b print_bad_pte+0x1af/0x250 unmap_page_range+0x7a7/0x8a0 unmap_single_vma+0x81/0xf0 unmap_vmas+0x49/0x90 unmap_region+0xbe/0x140 ? vma_rb_erase+0x121/0x220 do_munmap+0x245/0x420 vm_munmap+0x41/0x60 SyS_munmap+0x22/0x30 tracesys+0xdd/0xe2 Signed-off-by: Arun Easi <[email protected]> Signed-off-by: Manish Rangankar <[email protected]> Signed-off-by: Martin K. Petersen <[email protected]>
1 parent 0648a07 commit 5e901d0

File tree

1 file changed

+11
-12
lines changed

1 file changed

+11
-12
lines changed

drivers/scsi/qedi/qedi_main.c

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,11 @@ static int qedi_uio_close(struct uio_info *uinfo, struct inode *inode)
151151

152152
static void __qedi_free_uio_rings(struct qedi_uio_dev *udev)
153153
{
154+
if (udev->uctrl) {
155+
free_page((unsigned long)udev->uctrl);
156+
udev->uctrl = NULL;
157+
}
158+
154159
if (udev->ll2_ring) {
155160
free_page((unsigned long)udev->ll2_ring);
156161
udev->ll2_ring = NULL;
@@ -169,7 +174,6 @@ static void __qedi_free_uio(struct qedi_uio_dev *udev)
169174
__qedi_free_uio_rings(udev);
170175

171176
pci_dev_put(udev->pdev);
172-
kfree(udev->uctrl);
173177
kfree(udev);
174178
}
175179

@@ -208,6 +212,11 @@ static int __qedi_alloc_uio_rings(struct qedi_uio_dev *udev)
208212
if (udev->ll2_ring || udev->ll2_buf)
209213
return rc;
210214

215+
/* Memory for control area. */
216+
udev->uctrl = (void *)get_zeroed_page(GFP_KERNEL);
217+
if (!udev->uctrl)
218+
return -ENOMEM;
219+
211220
/* Allocating memory for LL2 ring */
212221
udev->ll2_ring_size = QEDI_PAGE_SIZE;
213222
udev->ll2_ring = (void *)get_zeroed_page(GFP_KERNEL | __GFP_COMP);
@@ -237,7 +246,6 @@ static int __qedi_alloc_uio_rings(struct qedi_uio_dev *udev)
237246
static int qedi_alloc_uio_rings(struct qedi_ctx *qedi)
238247
{
239248
struct qedi_uio_dev *udev = NULL;
240-
struct qedi_uio_ctrl *uctrl = NULL;
241249
int rc = 0;
242250

243251
list_for_each_entry(udev, &qedi_udev_list, list) {
@@ -258,21 +266,14 @@ static int qedi_alloc_uio_rings(struct qedi_ctx *qedi)
258266
goto err_udev;
259267
}
260268

261-
uctrl = kzalloc(sizeof(*uctrl), GFP_KERNEL);
262-
if (!uctrl) {
263-
rc = -ENOMEM;
264-
goto err_uctrl;
265-
}
266-
267269
udev->uio_dev = -1;
268270

269271
udev->qedi = qedi;
270272
udev->pdev = qedi->pdev;
271-
udev->uctrl = uctrl;
272273

273274
rc = __qedi_alloc_uio_rings(udev);
274275
if (rc)
275-
goto err_uio_rings;
276+
goto err_uctrl;
276277

277278
list_add(&udev->list, &qedi_udev_list);
278279

@@ -283,8 +284,6 @@ static int qedi_alloc_uio_rings(struct qedi_ctx *qedi)
283284
udev->rx_pkt = udev->ll2_buf + LL2_SINGLE_BUF_SIZE;
284285
return 0;
285286

286-
err_uio_rings:
287-
kfree(uctrl);
288287
err_uctrl:
289288
kfree(udev);
290289
err_udev:

0 commit comments

Comments
 (0)