Re: [PATCH 4/6] dma: tegra: add accurate reporting of dma state

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Ben,

I love your patch! Perhaps something to improve:

[auto build test WARNING on sof-driver-fuweitax/master]
[also build test WARNING on v4.19-rc7 next-20181012]
[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/Ben-Dooks/dma-tegra-avoid-overflow-of-byte-tracking/20181013-023951
base:   https://github.com/fuweitax/linux master
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 

Note: it may well be a FALSE warning. FWIW you are at least aware of it now.
http://gcc.gnu.org/wiki/Better_Uninitialized_Warnings

All warnings (new ones prefixed by >>):

   In file included from include/linux/printk.h:332:0,
                    from include/linux/kernel.h:14,
                    from include/linux/clk.h:16,
                    from drivers//dma/tegra20-apb-dma.c:20:
   drivers//dma/tegra20-apb-dma.c: In function 'tegra_dma_tx_status':
   include/linux/dynamic_debug.h:135:3: warning: 'done' may be used uninitialized in this function [-Wmaybe-uninitialized]
      __dynamic_dev_dbg(&descriptor, dev, fmt, \
      ^~~~~~~~~~~~~~~~~
   drivers//dma/tegra20-apb-dma.c:816:6: note: 'done' was declared here
     int done;
         ^~~~
   In file included from include/linux/printk.h:332:0,
                    from include/linux/kernel.h:14,
                    from include/linux/clk.h:16,
                    from drivers//dma/tegra20-apb-dma.c:20:
   include/linux/dynamic_debug.h:135:3: warning: 'wcount' may be used uninitialized in this function [-Wmaybe-uninitialized]
      __dynamic_dev_dbg(&descriptor, dev, fmt, \
      ^~~~~~~~~~~~~~~~~
   drivers//dma/tegra20-apb-dma.c:811:16: note: 'wcount' was declared here
     unsigned long wcount;
                   ^~~~~~
>> drivers//dma/tegra20-apb-dma.c:843:30: warning: 'sg_req' may be used uninitialized in this function [-Wmaybe-uninitialized]
       result = residual - sg_req->req_len;
                           ~~~~~~^~~~~~~~~
   drivers//dma/tegra20-apb-dma.c:894:27: note: 'sg_req' was declared here
     struct tegra_dma_sg_req *sg_req;
                              ^~~~~~

vim +/sg_req +843 drivers//dma/tegra20-apb-dma.c

   804	
   805	static unsigned int tegra_dma_update_residual(struct tegra_dma_channel *tdc,
   806						      struct tegra_dma_sg_req *sg_req,
   807						      struct tegra_dma_desc *dma_desc,
   808						      unsigned int residual)
   809	{
   810		unsigned long status = 0x0;
   811		unsigned long wcount;
   812		unsigned long ahbptr;
   813		unsigned long tmp = 0x0;
   814		unsigned int result;
   815		int retries = TEGRA_APBDMA_BURST_COMPLETE_TIME * 10;
   816		int done;
   817	
   818		/* if we're not the current request, then don't alter the residual */
   819		if (sg_req != list_first_entry(&tdc->pending_sg_req,
   820					       struct tegra_dma_sg_req, node)) {
   821			result = residual;
   822			ahbptr = 0xffffffff;
   823			goto done;
   824		}
   825	
   826		/* loop until we have a reliable result for residual */
   827		do {
   828			ahbptr = tdc_read(tdc, TEGRA_APBDMA_CHAN_AHBPTR);
   829			status = tdc_read(tdc, TEGRA_APBDMA_CHAN_STATUS);
   830			tmp =  tdc_read(tdc, 0x08);	/* total count for debug */
   831	
   832			/* check status, if channel isn't busy then skip */
   833			if (!(status & TEGRA_APBDMA_STATUS_BUSY)) {
   834				result = residual;
   835				break;
   836			}
   837	
   838			/* if we've got an interrupt pending on the channel, don't
   839			 * try and deal with the residue as the hardware has likely
   840			 * moved on to the next buffer. return all data moved.
   841			 */
   842			if (status & TEGRA_APBDMA_STATUS_ISE_EOC) {
 > 843				result = residual - sg_req->req_len;
   844				break;
   845			}
   846	
   847			if (tdc->tdma->chip_data->support_separate_wcount_reg)
   848				wcount = tdc_read(tdc, TEGRA_APBDMA_CHAN_WORD_TRANSFER);
   849			else
   850				wcount = status;
   851	
   852			/* If the request is at the full point, then there is a
   853			 * chance that we have read the status register in the
   854			 * middle of the hardware reloading the next buffer.
   855			 *
   856			 * The sequence seems to be at the end of the buffer, to
   857			 * load the new word count before raising the EOC flag (or
   858			 * changing the ping-pong flag which could have also been
   859			 * used to determine a new buffer). This  means there is a
   860			 * small window where we cannot determine zero-done for the
   861			 * current buffer, or moved to next buffer.
   862			 *
   863			 * If done shows 0, then retry the load, as it may hit the
   864			 * above hardware race. We will either get a new value which
   865			 * is from the first buffer, or we get an EOC (new buffer)
   866			 * or both a new value and an EOC...
   867			 */
   868			done = get_current_xferred_count(tdc, sg_req, wcount);
   869			if (done != 0) {
   870				result = residual - done;
   871				break;
   872			}
   873	
   874			ndelay(100);
   875		} while (--retries > 0);
   876	
   877		if (retries <= 0) {
   878			dev_err(tdc2dev(tdc), "timeout waiting for dma load\n");
   879			result = residual;
   880		}
   881	

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

Attachment: .config.gz
Description: application/gzip


[Index of Archives]     [ARM Kernel]     [Linux ARM]     [Linux ARM MSM]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux