Hi Matt, Thank you for the patch! Perhaps something to improve: [auto build test WARNING on staging/staging-testing] [cannot apply to v5.1-rc6 next-20190418] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Matt-Sickler/staging-kpc2000-Add-DMA-driver/20190423-120446 config: arm-allmodconfig (attached as .config) compiler: arm-linux-gnueabi-gcc (Debian 7.2.0-11) 7.2.0 reproduce: wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree GCC_VERSION=7.2.0 make.cross ARCH=arm If you fix the issue, kindly add following tag Reported-by: kbuild test robot <lkp@xxxxxxxxx> All warnings (new ones prefixed by >>): In file included from include/linux/printk.h:330:0, from include/linux/kernel.h:15, from include/linux/list.h:9, from include/linux/module.h:9, from drivers/staging//kpc2000/kpc_dma/fileops.c:2: drivers/staging//kpc2000/kpc_dma/fileops.c: In function 'kpc_dma_transfer': >> drivers/staging//kpc2000/kpc_dma/fileops.c:58:35: warning: format '%ld' expects argument of type 'long int', but argument 7 has type 'size_t {aka unsigned int}' [-Wformat=] dev_dbg(&priv->ldev->pldev->dev, "kpc_dma_transfer(priv = [%p], kcb = [%p], iov_base = [%p], iov_len = %ld) ldev = [%p]\n", priv, kcb, (void*)iov_base, iov_len, ldev); ^ include/linux/dynamic_debug.h:118:15: note: in definition of macro '__dynamic_func_call' func(&id, ##__VA_ARGS__); \ ^~~~~~~~~~~ include/linux/dynamic_debug.h:150:2: note: in expansion of macro '_dynamic_func_call' _dynamic_func_call(fmt,__dynamic_dev_dbg, \ ^~~~~~~~~~~~~~~~~~ include/linux/device.h:1493:2: note: in expansion of macro 'dynamic_dev_dbg' dynamic_dev_dbg(dev, dev_fmt(fmt), ##__VA_ARGS__) ^~~~~~~~~~~~~~~ include/linux/device.h:1493:23: note: in expansion of macro 'dev_fmt' dynamic_dev_dbg(dev, dev_fmt(fmt), ##__VA_ARGS__) ^~~~~~~ drivers/staging//kpc2000/kpc_dma/fileops.c:58:2: note: in expansion of macro 'dev_dbg' dev_dbg(&priv->ldev->pldev->dev, "kpc_dma_transfer(priv = [%p], kcb = [%p], iov_base = [%p], iov_len = %ld) ldev = [%p]\n", priv, kcb, (void*)iov_base, iov_len, ldev); ^~~~~~~ vim +58 drivers/staging//kpc2000/kpc_dma/fileops.c > 2 #include <linux/module.h> 3 #include <linux/init.h> 4 #include <linux/mm.h> 5 #include <linux/kernel.h> /* printk() */ 6 #include <linux/slab.h> /* kmalloc() */ 7 #include <linux/fs.h> /* everything... */ 8 #include <linux/errno.h> /* error codes */ 9 #include <linux/types.h> /* size_t */ 10 #include <linux/cdev.h> 11 #include <asm/uaccess.h> /* copy_*_user */ 12 #include <linux/aio.h> /* aio stuff */ 13 #include <linux/highmem.h> 14 #include <linux/pagemap.h> 15 #include "kpc_dma_driver.h" 16 #include "uapi.h" 17 18 /********** Helper Functions **********/ 19 static inline 20 unsigned int count_pages(unsigned long iov_base, size_t iov_len) 21 { 22 unsigned long first = (iov_base & PAGE_MASK) >> PAGE_SHIFT; 23 unsigned long last = ((iov_base+iov_len-1) & PAGE_MASK) >> PAGE_SHIFT; 24 return last - first + 1; 25 } 26 27 static inline 28 unsigned int count_parts_for_sge(struct scatterlist *sg) 29 { 30 unsigned int sg_length = sg_dma_len(sg); 31 sg_length += (0x80000-1); 32 return (sg_length / 0x80000); 33 } 34 35 /********** Transfer Helpers **********/ 36 static 37 int kpc_dma_transfer(struct dev_private_data *priv, struct kiocb *kcb, unsigned long iov_base, size_t iov_len) 38 { 39 unsigned int i = 0; 40 long rv = 0; 41 struct kpc_dma_device *ldev; 42 struct aio_cb_data *acd; 43 DECLARE_COMPLETION_ONSTACK(done); 44 u32 desc_needed = 0; 45 struct scatterlist *sg; 46 u32 num_descrs_avail; 47 struct kpc_dma_descriptor *desc; 48 unsigned int pcnt; 49 unsigned int p; 50 u64 card_addr; 51 u64 dma_addr; 52 u64 user_ctl; 53 54 BUG_ON(priv == NULL); 55 ldev = priv->ldev; 56 BUG_ON(ldev == NULL); 57 > 58 dev_dbg(&priv->ldev->pldev->dev, "kpc_dma_transfer(priv = [%p], kcb = [%p], iov_base = [%p], iov_len = %ld) ldev = [%p]\n", priv, kcb, (void*)iov_base, iov_len, ldev); 59 60 acd = (struct aio_cb_data *) kzalloc(sizeof(struct aio_cb_data), GFP_KERNEL); 61 if (!acd){ 62 dev_err(&priv->ldev->pldev->dev, "Couldn't kmalloc space for for the aio data\n"); 63 return -ENOMEM; 64 } 65 memset(acd, 0x66, sizeof(struct aio_cb_data)); 66 67 acd->priv = priv; 68 acd->ldev = priv->ldev; 69 acd->cpl = &done; 70 acd->flags = 0; 71 acd->kcb = kcb; 72 acd->len = iov_len; 73 acd->page_count = count_pages(iov_base, iov_len); 74 75 // Allocate an array of page pointers 76 acd->user_pages = kzalloc(sizeof(struct page *) * acd->page_count, GFP_KERNEL); 77 if (!acd->user_pages){ 78 dev_err(&priv->ldev->pldev->dev, "Couldn't kmalloc space for for the page pointers\n"); 79 rv = -ENOMEM; 80 goto err_alloc_userpages; 81 } 82 83 // Lock the user buffer pages in memory, and hold on to the page pointers (for the sglist) 84 down_read(¤t->mm->mmap_sem); /* get memory map semaphore */ 85 rv = get_user_pages(iov_base, acd->page_count, FOLL_TOUCH | FOLL_WRITE | FOLL_GET, acd->user_pages, NULL); 86 up_read(¤t->mm->mmap_sem); /* release the semaphore */ 87 if (rv != acd->page_count){ 88 dev_err(&priv->ldev->pldev->dev, "Couldn't get_user_pages (%ld)\n", rv); 89 goto err_get_user_pages; 90 } 91 92 // Allocate and setup the sg_table (scatterlist entries) 93 rv = sg_alloc_table_from_pages(&acd->sgt, acd->user_pages, acd->page_count, iov_base & (PAGE_SIZE-1), iov_len, GFP_KERNEL); 94 if (rv){ 95 dev_err(&priv->ldev->pldev->dev, "Couldn't alloc sg_table (%ld)\n", rv); 96 goto err_alloc_sg_table; 97 } 98 99 // Setup the DMA mapping for all the sg entries 100 acd->mapped_entry_count = dma_map_sg(&ldev->pldev->dev, acd->sgt.sgl, acd->sgt.nents, ldev->dir); 101 if (acd->mapped_entry_count <= 0){ 102 dev_err(&priv->ldev->pldev->dev, "Couldn't dma_map_sg (%d)\n", acd->mapped_entry_count); 103 goto err_dma_map_sg; 104 } 105 106 // Calculate how many descriptors are actually needed for this transfer. 107 for_each_sg(acd->sgt.sgl, sg, acd->mapped_entry_count, i){ 108 desc_needed += count_parts_for_sge(sg); 109 } 110 111 lock_engine(ldev); 112 113 // Figoure out how many descriptors are available and return an error if there aren't enough 114 num_descrs_avail = count_descriptors_available(ldev); 115 dev_dbg(&priv->ldev->pldev->dev, " mapped_entry_count = %d num_descrs_needed = %d num_descrs_avail = %d\n", acd->mapped_entry_count, desc_needed, num_descrs_avail); 116 if (desc_needed >= ldev->desc_pool_cnt){ 117 dev_warn(&priv->ldev->pldev->dev, " mapped_entry_count = %d num_descrs_needed = %d num_descrs_avail = %d TOO MANY to ever complete!\n", acd->mapped_entry_count, desc_needed, num_descrs_avail); 118 rv = -EAGAIN; 119 unlock_engine(ldev); 120 goto err_descr_too_many; 121 } 122 if (desc_needed > num_descrs_avail){ 123 dev_warn(&priv->ldev->pldev->dev, " mapped_entry_count = %d num_descrs_needed = %d num_descrs_avail = %d Too many to complete right now.\n", acd->mapped_entry_count, desc_needed, num_descrs_avail); 124 rv = -EMSGSIZE; 125 unlock_engine(ldev); 126 goto err_descr_too_many; 127 } 128 129 // Loop through all the sg table entries and fill out a descriptor for each one. 130 desc = ldev->desc_next; 131 card_addr = acd->priv->card_addr; 132 for_each_sg(acd->sgt.sgl, sg, acd->mapped_entry_count, i){ 133 pcnt = count_parts_for_sge(sg); 134 for (p = 0 ; p < pcnt ; p++){ 135 // Fill out the descriptor 136 BUG_ON(desc == NULL); 137 clear_desc(desc); 138 if (p != pcnt-1){ 139 desc->DescByteCount = 0x80000; 140 } else { 141 desc->DescByteCount = sg_dma_len(sg) - (p * 0x80000); 142 } 143 desc->DescBufferByteCount = desc->DescByteCount; 144 145 desc->DescControlFlags |= DMA_DESC_CTL_IRQONERR; 146 if (i == 0 && p == 0) 147 desc->DescControlFlags |= DMA_DESC_CTL_SOP; 148 if (i == acd->mapped_entry_count-1 && p == pcnt-1) 149 desc->DescControlFlags |= DMA_DESC_CTL_EOP | DMA_DESC_CTL_IRQONDONE; 150 151 desc->DescCardAddrLS = (card_addr & 0xFFFFFFFF); 152 desc->DescCardAddrMS = (card_addr >> 32) & 0xF; 153 card_addr += desc->DescByteCount; 154 155 dma_addr = sg_dma_address(sg) + (p * 0x80000); 156 desc->DescSystemAddrLS = (dma_addr & 0x00000000FFFFFFFF) >> 0; 157 desc->DescSystemAddrMS = (dma_addr & 0xFFFFFFFF00000000) >> 32; 158 159 user_ctl = acd->priv->user_ctl; 160 if (i == acd->mapped_entry_count-1 && p == pcnt-1){ 161 user_ctl = acd->priv->user_ctl_last; 162 } 163 desc->DescUserControlLS = (user_ctl & 0x00000000FFFFFFFF) >> 0; 164 desc->DescUserControlMS = (user_ctl & 0xFFFFFFFF00000000) >> 32; 165 166 if (i == acd->mapped_entry_count-1 && p == pcnt-1) 167 desc->acd = acd; 168 169 dev_dbg(&priv->ldev->pldev->dev, " Filled descriptor %p (acd = %p)\n", desc, desc->acd); 170 171 ldev->desc_next = desc->Next; 172 desc = desc->Next; 173 } 174 } 175 176 // Send the filled descriptors off to the hardware to process! 177 SetEngineSWPtr(ldev, ldev->desc_next); 178 179 unlock_engine(ldev); 180 181 // If this is a synchronous kiocb, we need to put the calling process to sleep until the transfer is complete 182 if (kcb == NULL || is_sync_kiocb(kcb)){ 183 rv = wait_for_completion_interruptible(&done); 184 // If the user aborted (rv == -ERESTARTSYS), we're no longer responsible for cleaning up the acd 185 if (rv == -ERESTARTSYS){ 186 acd->cpl = NULL; 187 } 188 if (rv == 0){ 189 rv = acd->len; 190 kfree(acd); 191 } 192 return rv; 193 } 194 195 return -EIOCBQUEUED; 196 197 err_descr_too_many: 198 unlock_engine(ldev); 199 dma_unmap_sg(&ldev->pldev->dev, acd->sgt.sgl, acd->sgt.nents, ldev->dir); 200 sg_free_table(&acd->sgt); 201 err_dma_map_sg: 202 err_alloc_sg_table: 203 for (i = 0 ; i < acd->page_count ; i++){ 204 put_page(acd->user_pages[i]); 205 } 206 err_get_user_pages: 207 kfree(acd->user_pages); 208 err_alloc_userpages: 209 kfree(acd); 210 dev_dbg(&priv->ldev->pldev->dev, "kpc_dma_transfer returning with error %ld\n", rv); 211 return rv; 212 } 213 --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation
Attachment:
.config.gz
Description: application/gzip
_______________________________________________ devel mailing list devel@xxxxxxxxxxxxxxxxxxxxxx http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel