IB/qib: Fix DMA api warning with debug kernel
Subsystems (2)
PATCH 1/1 IB/qib: Fix DMA api warning with debug kernel
From: Mike Marciniszyn <[email protected]>
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.
---
I'd rank this one alongside [1] as to whether it should go to -rc or -next. I'm pretty much fine with either.
[1] https://marc.info/?l=linux-rdma&m=152643430302065&w=2
--- drivers/infiniband/hw/qib/qib.h | 3 +-- drivers/infiniband/hw/qib/qib_file_ops.c | 10 +++++++--- drivers/infiniband/hw/qib/qib_user_pages.c | 20 ++++++++++++-------- 3 files changed, 20 insertions(+), 13 deletions(-)
drivers/infiniband/hw/qib/qib.h +1 -2
@@ -1424,8 +1424,7 @@ int qib_pcie_ddinit(struct qib_devdata *, struct pci_dev *,/* * dma_addr wrappers - all 0's invalid for hw */ -dma_addr_t qib_map_page (struct pci_dev *,struct page *,unsigned long , -size_t ,int ); +int qib_map_page (struct pci_dev *d,struct page *p,dma_addr_t *daddr);struct pci_dev *qib_get_pci_dev (struct rvt_dev_info *rdi);/*
drivers/infiniband/hw/qib/qib_file_ops.c +7 -3
@@ -364,6 +364,8 @@ static int qib_tid_update(struct qib_ctxtdata *rcd, struct file *fp, goto done; }for (i =0 ; i < cnt; i++, vaddr +=PAGE_SIZE ) { +dma_addr_t daddr; +for (; ntids--; tid++) {if (tid == tidcnt) tid =0 ;
@@ -380,12 +382,14 @@ static int qib_tid_update(struct qib_ctxtdata *rcd, struct file *fp, ret = -ENOMEM ;break ; } + ret =qib_map_page (dd->pcidev, pagep[i], &daddr); +if (ret) +break ; + tidlist[i] = tid + tidoff;/* we "know" system pages and TID pages are same size */ dd->pageshadow[ctxttid + tid] = pagep[i]; - dd->physshadow[ctxttid + tid] = -qib_map_page (dd->pcidev, pagep[i],0 ,PAGE_SIZE , -PCI_DMA_FROMDEVICE ); + dd->physshadow[ctxttid + tid] = daddr;/* * don't need atomic or it's overhead */
drivers/infiniband/hw/qib/qib_user_pages.c +12 -8
@@ -99,23 +99,27 @@ static int __qib_get_user_pages(unsigned long start_page, size_t num_pages,* * I'm sure we won't be so lucky with other iommu's, so FIXME. */ -dma_addr_t qib_map_page (struct pci_dev *hwdev,struct page *page, -unsigned long offset,size_t size,int direction) +int qib_map_page (struct pci_dev *hwdev,struct page *page,dma_addr_t *daddr) {dma_addr_t phys; - phys =pci_map_page (hwdev, page, offset, size, direction); + phys =pci_map_page (hwdev, page,0 ,PAGE_SIZE ,PCI_DMA_FROMDEVICE ); +if (pci_dma_mapping_error (hwdev, phys)) +return -ENOMEM ; -if (phys ==0 ) { -pci_unmap_page (hwdev, phys, size, direction); - phys =pci_map_page (hwdev, page, offset, size, direction); +if (!phys) { +pci_unmap_page (hwdev, phys,PAGE_SIZE ,PCI_DMA_FROMDEVICE ); + phys =pci_map_page (hwdev, page,0 ,PAGE_SIZE , +PCI_DMA_FROMDEVICE ); +if (pci_dma_mapping_error (hwdev, phys)) +return -ENOMEM ;/* * FIXME: If we get 0 again, we should keep this page, * map another, then free the 0 page. */ } - -return phys; + *daddr = phys; +return 0 ; }/**
Doug Ledford
AppliedQuoted 52 lines · Dennis Dalessandro
From: Mike Marciniszyn <[email protected]>
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 rpcrdmasunrpc
ib_srpscsi_transport_srpscsi_tgtib_iserlibiscsiib_ipoibscsi_transport_iscsirdma_ucmib_ucmib_uverbsib_umadrdma_cmib_cmiw_cmib_qibintel_powerclampcoretemp rdmavtintel_rapliosf_mbikvm_intelkvm irqbypasscrc32_pclmulghash_clmulni_intelipmi_ssifib_coreaesni_intelsgipmi_silrw gf128mul dcaglue_helperipmi_devintfiTCO_wdtgpio_ichhpwdtiTCO_vendor_supportablk_helperhpiloacpi_power_metercryptdipmi_msghandlerie31200_edacshpchppcc_cpufreqlpc_ichpcspkrip_tablesxfs libcrc32csd_modcrc_t10difcrct10dif_genericmgag200i2c_algo_bitdrm_kms_helpersyscopyarea sysfillrect sysimgbltfb_sys_fopsttm ahcicrct10dif_pclmulcrct10dif_commondrmcrc32c_intellibahci tg3 libataserio_rawptpi2c_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/0x21The 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.
Quoted 6 lines
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]>
Thanks, applied to for-next.
Signature · 3 lines
Doug Ledford <[email protected]> GPG KeyID: B826A3330E572FDD Key fingerprint = AE6B 1BDA 122B 23B4 265B 1274 B826 A333 0E57 2FDD