Skip to content

Commit e884ed8

Browse files
mmarcinigregkh
authored andcommitted
IB/qib: Fix DMA api warning with debug kernel
commit 0252f73 upstream. The following error occurs in a debug build when running MPI PSM: [ 307.415911] WARNING: CPU: 4 PID: 23867 at lib/dma-debug.c:1158 check_unmap+0x4ee/0xa20 [ 307.455661] ib_qib 0000:05:00.0: DMA-API: device driver failed to check map error[device address=0x00000000df82b000] [size=4096 bytes] [mapped as page] [ 307.517494] Modules linked in: [ 307.531584] ib_isert iscsi_target_mod ib_srpt target_core_mod rpcrdma sunrpc ib_srp scsi_transport_srp scsi_tgt ib_iser libiscsi ib_ipoib scsi_transport_iscsi rdma_ucm ib_ucm ib_uverbs ib_umad rdma_cm ib_cm iw_cm ib_qib intel_powerclamp coretemp rdmavt intel_rapl iosf_mbi kvm_intel kvm irqbypass crc32_pclmul ghash_clmulni_intel ipmi_ssif ib_core aesni_intel sg ipmi_si lrw gf128mul dca glue_helper ipmi_devintf iTCO_wdt gpio_ich hpwdt iTCO_vendor_support ablk_helper hpilo acpi_power_meter cryptd ipmi_msghandler ie31200_edac shpchp pcc_cpufreq lpc_ich pcspkr ip_tables xfs libcrc32c sd_mod crc_t10dif crct10dif_generic mgag200 i2c_algo_bit drm_kms_helper syscopyarea sysfillrect sysimgblt fb_sys_fops ttm ahci crct10dif_pclmul crct10dif_common drm crc32c_intel libahci tg3 libata serio_raw ptp i2c_core [ 307.846113] pps_core dm_mirror dm_region_hash dm_log dm_mod [ 307.866505] CPU: 4 PID: 23867 Comm: mpitests-IMB-MP Kdump: loaded Not tainted 3.10.0-862.el7.x86_64.debug #1 [ 307.911178] Hardware name: HP ProLiant DL320e Gen8, BIOS J05 11/09/2013 [ 307.944206] Call Trace: [ 307.956973] [<ffffffffbd9e915b>] dump_stack+0x19/0x1b [ 307.982201] [<ffffffffbd2a2f58>] __warn+0xd8/0x100 [ 308.005999] [<ffffffffbd2a2fdf>] warn_slowpath_fmt+0x5f/0x80 [ 308.034260] [<ffffffffbd5f667e>] check_unmap+0x4ee/0xa20 [ 308.060801] [<ffffffffbd41acaa>] ? page_add_file_rmap+0x2a/0x1d0 [ 308.090689] [<ffffffffbd5f6c4d>] debug_dma_unmap_page+0x9d/0xb0 [ 308.120155] [<ffffffffbd4082e0>] ? might_fault+0xa0/0xb0 [ 308.146656] [<ffffffffc07761a5>] qib_tid_free.isra.14+0x215/0x2a0 [ib_qib] [ 308.180739] [<ffffffffc0776bf4>] qib_write+0x894/0x1280 [ib_qib] [ 308.210733] [<ffffffffbd540b00>] ? __inode_security_revalidate+0x70/0x80 [ 308.244837] [<ffffffffbd53c2b7>] ? security_file_permission+0x27/0xb0 [ 308.266025] qib_ib0.8006: multicast join failed for ff12:401b:8006:0000:0000:0000:ffff:ffff, status -22 [ 308.323421] [<ffffffffbd46f5d3>] vfs_write+0xc3/0x1f0 [ 308.347077] [<ffffffffbd492a5c>] ? fget_light+0xfc/0x510 [ 308.372533] [<ffffffffbd47045a>] SyS_write+0x8a/0x100 [ 308.396456] [<ffffffffbd9ff355>] system_call_fastpath+0x1c/0x21 The code calls a qib_map_page() which has never correctly tested for a mapping error. Fix by testing for pci_dma_mapping_error() in all cases and properly handling the failure in the caller. Additionally, streamline qib_map_page() arguments to satisfy just the single caller. Cc: <[email protected]> Reviewed-by: Alex Estrin <[email protected]> Tested-by: Don Dutile <[email protected]> Reviewed-by: Don Dutile <[email protected]> Signed-off-by: Mike Marciniszyn <[email protected]> Signed-off-by: Dennis Dalessandro <[email protected]> Signed-off-by: Doug Ledford <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent c41cb9c commit e884ed8

File tree

3 files changed

+20
-13
lines changed

3 files changed

+20
-13
lines changed

drivers/infiniband/hw/qib/qib.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1448,8 +1448,7 @@ u64 qib_sps_ints(void);
14481448
/*
14491449
* dma_addr wrappers - all 0's invalid for hw
14501450
*/
1451-
dma_addr_t qib_map_page(struct pci_dev *, struct page *, unsigned long,
1452-
size_t, int);
1451+
int qib_map_page(struct pci_dev *d, struct page *p, dma_addr_t *daddr);
14531452
const char *qib_get_unit_name(int unit);
14541453
const char *qib_get_card_name(struct rvt_dev_info *rdi);
14551454
struct pci_dev *qib_get_pci_dev(struct rvt_dev_info *rdi);

drivers/infiniband/hw/qib/qib_file_ops.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,8 @@ static int qib_tid_update(struct qib_ctxtdata *rcd, struct file *fp,
364364
goto done;
365365
}
366366
for (i = 0; i < cnt; i++, vaddr += PAGE_SIZE) {
367+
dma_addr_t daddr;
368+
367369
for (; ntids--; tid++) {
368370
if (tid == tidcnt)
369371
tid = 0;
@@ -380,12 +382,14 @@ static int qib_tid_update(struct qib_ctxtdata *rcd, struct file *fp,
380382
ret = -ENOMEM;
381383
break;
382384
}
385+
ret = qib_map_page(dd->pcidev, pagep[i], &daddr);
386+
if (ret)
387+
break;
388+
383389
tidlist[i] = tid + tidoff;
384390
/* we "know" system pages and TID pages are same size */
385391
dd->pageshadow[ctxttid + tid] = pagep[i];
386-
dd->physshadow[ctxttid + tid] =
387-
qib_map_page(dd->pcidev, pagep[i], 0, PAGE_SIZE,
388-
PCI_DMA_FROMDEVICE);
392+
dd->physshadow[ctxttid + tid] = daddr;
389393
/*
390394
* don't need atomic or it's overhead
391395
*/

drivers/infiniband/hw/qib/qib_user_pages.c

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -99,23 +99,27 @@ static int __qib_get_user_pages(unsigned long start_page, size_t num_pages,
9999
*
100100
* I'm sure we won't be so lucky with other iommu's, so FIXME.
101101
*/
102-
dma_addr_t qib_map_page(struct pci_dev *hwdev, struct page *page,
103-
unsigned long offset, size_t size, int direction)
102+
int qib_map_page(struct pci_dev *hwdev, struct page *page, dma_addr_t *daddr)
104103
{
105104
dma_addr_t phys;
106105

107-
phys = pci_map_page(hwdev, page, offset, size, direction);
106+
phys = pci_map_page(hwdev, page, 0, PAGE_SIZE, PCI_DMA_FROMDEVICE);
107+
if (pci_dma_mapping_error(hwdev, phys))
108+
return -ENOMEM;
108109

109-
if (phys == 0) {
110-
pci_unmap_page(hwdev, phys, size, direction);
111-
phys = pci_map_page(hwdev, page, offset, size, direction);
110+
if (!phys) {
111+
pci_unmap_page(hwdev, phys, PAGE_SIZE, PCI_DMA_FROMDEVICE);
112+
phys = pci_map_page(hwdev, page, 0, PAGE_SIZE,
113+
PCI_DMA_FROMDEVICE);
114+
if (pci_dma_mapping_error(hwdev, phys))
115+
return -ENOMEM;
112116
/*
113117
* FIXME: If we get 0 again, we should keep this page,
114118
* map another, then free the 0 page.
115119
*/
116120
}
117-
118-
return phys;
121+
*daddr = phys;
122+
return 0;
119123
}
120124

121125
/**

0 commit comments

Comments
 (0)