Message ID | 20211018120055.2902897-1-u.kleine-koenig@pengutronix.de (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | usb: max-3421: Use driver data instead of maintaining a list of bound devices | expand |
Hi "Uwe,
I love your patch! Perhaps something to improve:
[auto build test WARNING on usb/usb-testing]
[also build test WARNING on v5.15-rc6 next-20211018]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]
url: https://github.com/0day-ci/linux/commits/Uwe-Kleine-K-nig/usb-max-3421-Use-driver-data-instead-of-maintaining-a-list-of-bound-devices/20211018-200133
base: https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git usb-testing
config: i386-randconfig-r025-20211018 (attached as .config)
compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project d245f2e8597bfb52c34810a328d42b990e4af1a4)
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://github.com/0day-ci/linux/commit/9ee7ff2f570093a02d9ae5e402a5becfdf87b9f5
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Uwe-Kleine-K-nig/usb-max-3421-Use-driver-data-instead-of-maintaining-a-list-of-bound-devices/20211018-200133
git checkout 9ee7ff2f570093a02d9ae5e402a5becfdf87b9f5
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 ARCH=i386
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
All warnings (new ones prefixed by >>):
>> drivers/usb/host/max3421-hcd.c:1880:18: warning: variable 'max3421_hcd' is uninitialized when used here [-Wuninitialized]
INIT_LIST_HEAD(&max3421_hcd->ep_list);
^~~~~~~~~~~
drivers/usb/host/max3421-hcd.c:1827:33: note: initialize the variable 'max3421_hcd' to silence this warning
struct max3421_hcd *max3421_hcd;
^
= NULL
1 warning generated.
vim +/max3421_hcd +1880 drivers/usb/host/max3421-hcd.c
721fdc83b31b1b Jules Maselbas 2017-09-15 1822
2d53139f31626b David Mosberger 2014-04-28 1823 static int
2d53139f31626b David Mosberger 2014-04-28 1824 max3421_probe(struct spi_device *spi)
2d53139f31626b David Mosberger 2014-04-28 1825 {
721fdc83b31b1b Jules Maselbas 2017-09-15 1826 struct device *dev = &spi->dev;
2d53139f31626b David Mosberger 2014-04-28 1827 struct max3421_hcd *max3421_hcd;
05dfa5c9bc3793 David Mosberger-Tang 2014-05-28 1828 struct usb_hcd *hcd = NULL;
721fdc83b31b1b Jules Maselbas 2017-09-15 1829 struct max3421_hcd_platform_data *pdata = NULL;
5a569343e8a618 Yang Yingliang 2020-11-17 1830 int retval;
2d53139f31626b David Mosberger 2014-04-28 1831
2d53139f31626b David Mosberger 2014-04-28 1832 if (spi_setup(spi) < 0) {
2d53139f31626b David Mosberger 2014-04-28 1833 dev_err(&spi->dev, "Unable to setup SPI bus");
2d53139f31626b David Mosberger 2014-04-28 1834 return -EFAULT;
2d53139f31626b David Mosberger 2014-04-28 1835 }
2d53139f31626b David Mosberger 2014-04-28 1836
721fdc83b31b1b Jules Maselbas 2017-09-15 1837 if (!spi->irq) {
721fdc83b31b1b Jules Maselbas 2017-09-15 1838 dev_err(dev, "Failed to get SPI IRQ");
721fdc83b31b1b Jules Maselbas 2017-09-15 1839 return -EFAULT;
721fdc83b31b1b Jules Maselbas 2017-09-15 1840 }
721fdc83b31b1b Jules Maselbas 2017-09-15 1841
721fdc83b31b1b Jules Maselbas 2017-09-15 1842 if (IS_ENABLED(CONFIG_OF) && dev->of_node) {
721fdc83b31b1b Jules Maselbas 2017-09-15 1843 pdata = devm_kzalloc(&spi->dev, sizeof(*pdata), GFP_KERNEL);
721fdc83b31b1b Jules Maselbas 2017-09-15 1844 if (!pdata) {
721fdc83b31b1b Jules Maselbas 2017-09-15 1845 retval = -ENOMEM;
721fdc83b31b1b Jules Maselbas 2017-09-15 1846 goto error;
721fdc83b31b1b Jules Maselbas 2017-09-15 1847 }
721fdc83b31b1b Jules Maselbas 2017-09-15 1848 retval = max3421_of_vbus_en_pin(dev, pdata);
721fdc83b31b1b Jules Maselbas 2017-09-15 1849 if (retval)
721fdc83b31b1b Jules Maselbas 2017-09-15 1850 goto error;
721fdc83b31b1b Jules Maselbas 2017-09-15 1851
721fdc83b31b1b Jules Maselbas 2017-09-15 1852 spi->dev.platform_data = pdata;
721fdc83b31b1b Jules Maselbas 2017-09-15 1853 }
721fdc83b31b1b Jules Maselbas 2017-09-15 1854
721fdc83b31b1b Jules Maselbas 2017-09-15 1855 pdata = spi->dev.platform_data;
721fdc83b31b1b Jules Maselbas 2017-09-15 1856 if (!pdata) {
721fdc83b31b1b Jules Maselbas 2017-09-15 1857 dev_err(&spi->dev, "driver configuration data is not provided\n");
721fdc83b31b1b Jules Maselbas 2017-09-15 1858 retval = -EFAULT;
721fdc83b31b1b Jules Maselbas 2017-09-15 1859 goto error;
721fdc83b31b1b Jules Maselbas 2017-09-15 1860 }
721fdc83b31b1b Jules Maselbas 2017-09-15 1861 if (pdata->vbus_active_level > 1) {
721fdc83b31b1b Jules Maselbas 2017-09-15 1862 dev_err(&spi->dev, "vbus active level value %d is out of range (0/1)\n", pdata->vbus_active_level);
721fdc83b31b1b Jules Maselbas 2017-09-15 1863 retval = -EINVAL;
721fdc83b31b1b Jules Maselbas 2017-09-15 1864 goto error;
721fdc83b31b1b Jules Maselbas 2017-09-15 1865 }
721fdc83b31b1b Jules Maselbas 2017-09-15 1866 if (pdata->vbus_gpout < 1 || pdata->vbus_gpout > MAX3421_GPOUT_COUNT) {
721fdc83b31b1b Jules Maselbas 2017-09-15 1867 dev_err(&spi->dev, "vbus gpout value %d is out of range (1..8)\n", pdata->vbus_gpout);
721fdc83b31b1b Jules Maselbas 2017-09-15 1868 retval = -EINVAL;
721fdc83b31b1b Jules Maselbas 2017-09-15 1869 goto error;
721fdc83b31b1b Jules Maselbas 2017-09-15 1870 }
721fdc83b31b1b Jules Maselbas 2017-09-15 1871
5a569343e8a618 Yang Yingliang 2020-11-17 1872 retval = -ENOMEM;
2d53139f31626b David Mosberger 2014-04-28 1873 hcd = usb_create_hcd(&max3421_hcd_desc, &spi->dev,
2d53139f31626b David Mosberger 2014-04-28 1874 dev_name(&spi->dev));
2d53139f31626b David Mosberger 2014-04-28 1875 if (!hcd) {
2d53139f31626b David Mosberger 2014-04-28 1876 dev_err(&spi->dev, "failed to create HCD structure\n");
05dfa5c9bc3793 David Mosberger-Tang 2014-05-28 1877 goto error;
2d53139f31626b David Mosberger 2014-04-28 1878 }
2d53139f31626b David Mosberger 2014-04-28 1879 set_bit(HCD_FLAG_POLL_RH, &hcd->flags);
2d53139f31626b David Mosberger 2014-04-28 @1880 INIT_LIST_HEAD(&max3421_hcd->ep_list);
9ee7ff2f570093 Uwe Kleine-König 2021-10-18 1881 spi_set_drvdata(spi, max3421_hcd);
2d53139f31626b David Mosberger 2014-04-28 1882
05dfa5c9bc3793 David Mosberger-Tang 2014-05-28 1883 max3421_hcd->tx = kmalloc(sizeof(*max3421_hcd->tx), GFP_KERNEL);
13dcf780059417 Wolfram Sang 2016-08-25 1884 if (!max3421_hcd->tx)
05dfa5c9bc3793 David Mosberger-Tang 2014-05-28 1885 goto error;
05dfa5c9bc3793 David Mosberger-Tang 2014-05-28 1886 max3421_hcd->rx = kmalloc(sizeof(*max3421_hcd->rx), GFP_KERNEL);
13dcf780059417 Wolfram Sang 2016-08-25 1887 if (!max3421_hcd->rx)
05dfa5c9bc3793 David Mosberger-Tang 2014-05-28 1888 goto error;
05dfa5c9bc3793 David Mosberger-Tang 2014-05-28 1889
2d53139f31626b David Mosberger 2014-04-28 1890 max3421_hcd->spi_thread = kthread_run(max3421_spi_thread, hcd,
2d53139f31626b David Mosberger 2014-04-28 1891 "max3421_spi_thread");
2d53139f31626b David Mosberger 2014-04-28 1892 if (max3421_hcd->spi_thread == ERR_PTR(-ENOMEM)) {
2d53139f31626b David Mosberger 2014-04-28 1893 dev_err(&spi->dev,
2d53139f31626b David Mosberger 2014-04-28 1894 "failed to create SPI thread (out of memory)\n");
05dfa5c9bc3793 David Mosberger-Tang 2014-05-28 1895 goto error;
2d53139f31626b David Mosberger 2014-04-28 1896 }
2d53139f31626b David Mosberger 2014-04-28 1897
2d53139f31626b David Mosberger 2014-04-28 1898 retval = usb_add_hcd(hcd, 0, 0);
2d53139f31626b David Mosberger 2014-04-28 1899 if (retval) {
2d53139f31626b David Mosberger 2014-04-28 1900 dev_err(&spi->dev, "failed to add HCD\n");
05dfa5c9bc3793 David Mosberger-Tang 2014-05-28 1901 goto error;
2d53139f31626b David Mosberger 2014-04-28 1902 }
2d53139f31626b David Mosberger 2014-04-28 1903
2d53139f31626b David Mosberger 2014-04-28 1904 retval = request_irq(spi->irq, max3421_irq_handler,
2d53139f31626b David Mosberger 2014-04-28 1905 IRQF_TRIGGER_LOW, "max3421", hcd);
2d53139f31626b David Mosberger 2014-04-28 1906 if (retval < 0) {
2d53139f31626b David Mosberger 2014-04-28 1907 dev_err(&spi->dev, "failed to request irq %d\n", spi->irq);
05dfa5c9bc3793 David Mosberger-Tang 2014-05-28 1908 goto error;
2d53139f31626b David Mosberger 2014-04-28 1909 }
2d53139f31626b David Mosberger 2014-04-28 1910 return 0;
05dfa5c9bc3793 David Mosberger-Tang 2014-05-28 1911
05dfa5c9bc3793 David Mosberger-Tang 2014-05-28 1912 error:
721fdc83b31b1b Jules Maselbas 2017-09-15 1913 if (IS_ENABLED(CONFIG_OF) && dev->of_node && pdata) {
721fdc83b31b1b Jules Maselbas 2017-09-15 1914 devm_kfree(&spi->dev, pdata);
721fdc83b31b1b Jules Maselbas 2017-09-15 1915 spi->dev.platform_data = NULL;
721fdc83b31b1b Jules Maselbas 2017-09-15 1916 }
721fdc83b31b1b Jules Maselbas 2017-09-15 1917
05dfa5c9bc3793 David Mosberger-Tang 2014-05-28 1918 if (hcd) {
05dfa5c9bc3793 David Mosberger-Tang 2014-05-28 1919 kfree(max3421_hcd->tx);
05dfa5c9bc3793 David Mosberger-Tang 2014-05-28 1920 kfree(max3421_hcd->rx);
05dfa5c9bc3793 David Mosberger-Tang 2014-05-28 1921 if (max3421_hcd->spi_thread)
05dfa5c9bc3793 David Mosberger-Tang 2014-05-28 1922 kthread_stop(max3421_hcd->spi_thread);
05dfa5c9bc3793 David Mosberger-Tang 2014-05-28 1923 usb_put_hcd(hcd);
05dfa5c9bc3793 David Mosberger-Tang 2014-05-28 1924 }
05dfa5c9bc3793 David Mosberger-Tang 2014-05-28 1925 return retval;
2d53139f31626b David Mosberger 2014-04-28 1926 }
2d53139f31626b David Mosberger 2014-04-28 1927
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
On Mon, Oct 18, 2021 at 02:00:55PM +0200, Uwe Kleine-König wrote: > Instead of maintaining a single-linked list of devices that must be > searched linearly in .remove() just use spi_set_drvdata() to remember the > link between the spi device and the driver struct. Then the global list > and the next member can be dropped. > > This simplifies the driver, reduces the memory footprint and the time to > search the list. Also it makes obvious that there is always a corresponding > driver struct for a given device in .remove(), so the error path for > !max3421_hcd can be dropped, too. > > As a side effect this fixes a data inconsistency when .probe() races with > itself for a second max3421 device in manipulating max3421_hcd_list. A > similar race is fixed in .remove(), too. > > Fixes: 2d53139f3162 ("Add support for using a MAX3421E chip as a host driver.") > Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de> > --- > drivers/usb/host/max3421-hcd.c | 26 +++++--------------------- > 1 file changed, 5 insertions(+), 21 deletions(-) > > diff --git a/drivers/usb/host/max3421-hcd.c b/drivers/usb/host/max3421-hcd.c > index 59cc1bc7f12f..3e39f62904af 100644 > --- a/drivers/usb/host/max3421-hcd.c > +++ b/drivers/usb/host/max3421-hcd.c > @@ -125,8 +125,6 @@ struct max3421_hcd { > > struct task_struct *spi_thread; > > - struct max3421_hcd *next; > - > enum max3421_rh_state rh_state; > /* lower 16 bits contain port status, upper 16 bits the change mask: */ > u32 port_status; > @@ -174,8 +172,6 @@ struct max3421_ep { > u8 retransmit; /* packet needs retransmission */ > }; > > -static struct max3421_hcd *max3421_hcd_list; > - > #define MAX3421_FIFO_SIZE 64 > > #define MAX3421_SPI_DIR_RD 0 /* read register from MAX3421 */ > @@ -1881,10 +1877,8 @@ max3421_probe(struct spi_device *spi) > goto error; > } > set_bit(HCD_FLAG_POLL_RH, &hcd->flags); > - max3421_hcd = hcd_to_max3421(hcd); I don't think you should have deleted this line :( Did you test this? thanks, greg k-h
Hello Greg, On Mon, Oct 18, 2021 at 04:55:38PM +0200, Greg Kroah-Hartman wrote: > On Mon, Oct 18, 2021 at 02:00:55PM +0200, Uwe Kleine-König wrote: > > @@ -1881,10 +1877,8 @@ max3421_probe(struct spi_device *spi) > > goto error; > > } > > set_bit(HCD_FLAG_POLL_RH, &hcd->flags); > > - max3421_hcd = hcd_to_max3421(hcd); > > I don't think you should have deleted this line :( > > Did you test this? Only compile tested (and the warning the kernel robot found didn't happen in my amd64 build). I'll respin this patch. Best regards Uwe
diff --git a/drivers/usb/host/max3421-hcd.c b/drivers/usb/host/max3421-hcd.c index 59cc1bc7f12f..3e39f62904af 100644 --- a/drivers/usb/host/max3421-hcd.c +++ b/drivers/usb/host/max3421-hcd.c @@ -125,8 +125,6 @@ struct max3421_hcd { struct task_struct *spi_thread; - struct max3421_hcd *next; - enum max3421_rh_state rh_state; /* lower 16 bits contain port status, upper 16 bits the change mask: */ u32 port_status; @@ -174,8 +172,6 @@ struct max3421_ep { u8 retransmit; /* packet needs retransmission */ }; -static struct max3421_hcd *max3421_hcd_list; - #define MAX3421_FIFO_SIZE 64 #define MAX3421_SPI_DIR_RD 0 /* read register from MAX3421 */ @@ -1881,10 +1877,8 @@ max3421_probe(struct spi_device *spi) goto error; } set_bit(HCD_FLAG_POLL_RH, &hcd->flags); - max3421_hcd = hcd_to_max3421(hcd); - max3421_hcd->next = max3421_hcd_list; - max3421_hcd_list = max3421_hcd; INIT_LIST_HEAD(&max3421_hcd->ep_list); + spi_set_drvdata(spi, max3421_hcd); max3421_hcd->tx = kmalloc(sizeof(*max3421_hcd->tx), GFP_KERNEL); if (!max3421_hcd->tx) @@ -1934,28 +1928,18 @@ max3421_probe(struct spi_device *spi) static int max3421_remove(struct spi_device *spi) { - struct max3421_hcd *max3421_hcd = NULL, **prev; - struct usb_hcd *hcd = NULL; + struct max3421_hcd *max3421_hcd; + struct usb_hcd *hcd; unsigned long flags; - for (prev = &max3421_hcd_list; *prev; prev = &(*prev)->next) { - max3421_hcd = *prev; - hcd = max3421_to_hcd(max3421_hcd); - if (hcd->self.controller == &spi->dev) - break; - } - if (!max3421_hcd) { - dev_err(&spi->dev, "no MAX3421 HCD found for SPI device %p\n", - spi); - return -ENODEV; - } + max3421_hcd = spi_get_drvdata(spi); + hcd = max3421_to_hcd(max3421_hcd); usb_remove_hcd(hcd); spin_lock_irqsave(&max3421_hcd->lock, flags); kthread_stop(max3421_hcd->spi_thread); - *prev = max3421_hcd->next; spin_unlock_irqrestore(&max3421_hcd->lock, flags);
Instead of maintaining a single-linked list of devices that must be searched linearly in .remove() just use spi_set_drvdata() to remember the link between the spi device and the driver struct. Then the global list and the next member can be dropped. This simplifies the driver, reduces the memory footprint and the time to search the list. Also it makes obvious that there is always a corresponding driver struct for a given device in .remove(), so the error path for !max3421_hcd can be dropped, too. As a side effect this fixes a data inconsistency when .probe() races with itself for a second max3421 device in manipulating max3421_hcd_list. A similar race is fixed in .remove(), too. Fixes: 2d53139f3162 ("Add support for using a MAX3421E chip as a host driver.") Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de> --- drivers/usb/host/max3421-hcd.c | 26 +++++--------------------- 1 file changed, 5 insertions(+), 21 deletions(-)