Linux USB
 help / color / mirror / Atom feed
* [RFT] usb: class: cdc-wdm: switch to kfifo for buffering
@ 2026-04-30 12:18 Oliver Neukum
  2026-05-04 15:54 ` kernel test robot
  2026-05-04 20:37 ` kernel test robot
  0 siblings, 2 replies; 3+ messages in thread
From: Oliver Neukum @ 2026-04-30 12:18 UTC (permalink / raw)
  To: hanguidong02, linux-usb; +Cc: Oliver Neukum

The kfifo code is more efficient and takes care
of memory ordering without locking.

Signed-off-by: Oliver Neukum <oneukum@suse.com>
---
 drivers/usb/class/cdc-wdm.c | 60 ++++++++++++++++++-------------------
 1 file changed, 30 insertions(+), 30 deletions(-)

diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c
index 7556c0dac908..9185295f5376 100644
--- a/drivers/usb/class/cdc-wdm.c
+++ b/drivers/usb/class/cdc-wdm.c
@@ -27,6 +27,7 @@
 #include <linux/wwan.h>
 #include <asm/byteorder.h>
 #include <linux/unaligned.h>
+#include <linux/kfifo.h>
 #include <linux/usb/cdc-wdm.h>
 
 #define DRIVER_AUTHOR "Oliver Neukum"
@@ -77,7 +78,8 @@ struct wdm_device {
 	u8			*inbuf; /* buffer for response */
 	u8			*outbuf; /* buffer for command */
 	u8			*sbuf; /* buffer for status */
-	u8			*ubuf; /* buffer for copy to user space */
+
+	struct kfifo		ubuf; /* payload */
 
 	struct urb		*command;
 	struct urb		*response;
@@ -92,7 +94,6 @@ struct wdm_device {
 	u16			wMaxCommand;
 	u16			wMaxPacketSize;
 	__le16			inum;
-	int			length;
 	int			read;
 	int			count;
 	dma_addr_t		shandle;
@@ -170,6 +171,7 @@ static void wdm_in_callback(struct urb *urb)
 	struct wdm_device *desc = urb->context;
 	int status = urb->status;
 	int length = urb->actual_length;
+	int processed;
 
 	spin_lock_irqsave(&desc->iuspin, flags);
 	clear_bit(WDM_RESPONDING, &desc->flags);
@@ -218,17 +220,13 @@ static void wdm_in_callback(struct urb *urb)
 		goto skip_zlp;
 	}
 
-	if (length + desc->length > desc->wMaxCommand) {
-		/* The buffer would overflow */
-		set_bit(WDM_OVERFLOW, &desc->flags);
-	} else {
-		/* we may already be in overflow */
-		if (!test_bit(WDM_OVERFLOW, &desc->flags)) {
-			memmove(desc->ubuf + desc->length, desc->inbuf, length);
-			smp_wmb(); /* against wdm_read() */
-			WRITE_ONCE(desc->length, desc->length + length);
-		}
+	processed = kfifo_in(&desc->ubuf, desc->inbuf, length);
+	if (processed < length) {
+		 set_bit(WDM_OVERFLOW, &desc->flags);
+		 /* WDM_OVERFLOW must not be set after WDM_READ */
+		 smp_wmb(); /* against wdm_read() */
 	}
+
 skip_error:
 
 	if (desc->rerr) {
@@ -372,8 +370,8 @@ static void cleanup(struct wdm_device *desc)
 	kfree(desc->inbuf);
 	kfree(desc->orq);
 	kfree(desc->irq);
-	kfree(desc->ubuf);
 	free_urbs(desc);
+	kfifo_free(&desc->ubuf);
 	kfree(desc);
 }
 
@@ -524,7 +522,7 @@ static int service_outstanding_interrupt(struct wdm_device *desc)
 static ssize_t wdm_read
 (struct file *file, char __user *buffer, size_t count, loff_t *ppos)
 {
-	int rv, cntr;
+	int rv, cntr, done;
 	int i = 0;
 	struct wdm_device *desc = file->private_data;
 
@@ -533,8 +531,7 @@ static ssize_t wdm_read
 	if (rv < 0)
 		return -ERESTARTSYS;
 
-	cntr = READ_ONCE(desc->length);
-	smp_rmb(); /* against wdm_in_callback() */
+	cntr = kfifo_len(&desc->ubuf);
 	if (cntr == 0) {
 		desc->read = 0;
 retry:
@@ -568,6 +565,13 @@ static ssize_t wdm_read
 			rv = -EIO;
 			goto err;
 		}
+		smp_rmb(); /* against wdm_in_callback() */
+		if (test_bit(WDM_OVERFLOW, &desc->flags)) {
+			clear_bit(WDM_OVERFLOW, &desc->flags);
+			rv = -ENOBUFS;
+			goto err;
+		}
+
 		usb_mark_last_busy(interface_to_usbdev(desc->intf));
 		if (rv < 0) {
 			rv = -ERESTARTSYS;
@@ -591,31 +595,27 @@ static ssize_t wdm_read
 			goto retry;
 		}
 
-		cntr = desc->length;
+		cntr = kfifo_len(&desc->ubuf);
 		spin_unlock_irq(&desc->iuspin);
 	}
 
 	if (cntr > count)
 		cntr = count;
-	rv = copy_to_user(buffer, desc->ubuf, cntr);
-	if (rv > 0) {
+	rv = kfifo_to_user(&desc->ubuf, buffer, cntr, &done);
+	if (rv < 0) {
 		rv = -EFAULT;
 		goto err;
 	}
 
 	spin_lock_irq(&desc->iuspin);
 
-	for (i = 0; i < desc->length - cntr; i++)
-		desc->ubuf[i] = desc->ubuf[i + cntr];
-
-	desc->length -= cntr;
 	/* in case we had outstanding data */
-	if (!desc->length) {
+	if (kfifo_is_empty(&desc->ubuf)) {
 		clear_bit(WDM_READ, &desc->flags);
 		service_outstanding_interrupt(desc);
 	}
 	spin_unlock_irq(&desc->iuspin);
-	rv = cntr;
+	rv = done;
 
 err:
 	mutex_unlock(&desc->rlock);
@@ -1013,7 +1013,7 @@ static void service_interrupt_work(struct work_struct *work)
 
 	spin_lock_irq(&desc->iuspin);
 	service_outstanding_interrupt(desc);
-	if (!desc->resp_count && (desc->length || desc->rerr)) {
+	if (!desc->resp_count && (!kfifo_is_empty(&desc->ubuf) || desc->rerr)) {
 		set_bit(WDM_READ, &desc->flags);
 		wake_up(&desc->wait);
 	}
@@ -1071,10 +1071,6 @@ static int wdm_create(struct usb_interface *intf, struct usb_endpoint_descriptor
 	if (!desc->command)
 		goto err;
 
-	desc->ubuf = kmalloc(desc->wMaxCommand, GFP_KERNEL);
-	if (!desc->ubuf)
-		goto err;
-
 	desc->sbuf = kmalloc(desc->wMaxPacketSize, GFP_KERNEL);
 	if (!desc->sbuf)
 		goto err;
@@ -1083,6 +1079,10 @@ static int wdm_create(struct usb_interface *intf, struct usb_endpoint_descriptor
 	if (!desc->inbuf)
 		goto err;
 
+	rv = kfifo_alloc(&desc->ubuf, roundup_pow_of_two(desc->wMaxCommand), GFP_KERNEL);
+	if (rv < 0)
+		goto err;
+
 	usb_fill_int_urb(
 		desc->validity,
 		interface_to_usbdev(intf),
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [RFT] usb: class: cdc-wdm: switch to kfifo for buffering
  2026-04-30 12:18 [RFT] usb: class: cdc-wdm: switch to kfifo for buffering Oliver Neukum
@ 2026-05-04 15:54 ` kernel test robot
  2026-05-04 20:37 ` kernel test robot
  1 sibling, 0 replies; 3+ messages in thread
From: kernel test robot @ 2026-05-04 15:54 UTC (permalink / raw)
  To: Oliver Neukum, hanguidong02, linux-usb; +Cc: llvm, oe-kbuild-all, Oliver Neukum

Hi Oliver,

kernel test robot noticed the following build warnings:

[auto build test WARNING on usb/usb-testing]
[also build test WARNING on usb/usb-next usb/usb-linus westeri-thunderbolt/next linus/master v7.1-rc2 next-20260430]
[cannot apply to peter-chen-usb/for-usb-next]
[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#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Oliver-Neukum/usb-class-cdc-wdm-switch-to-kfifo-for-buffering/20260504-164851
base:   https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git usb-testing
patch link:    https://lore.kernel.org/r/20260430121859.1018894-1-oneukum%40suse.com
patch subject: [RFT] usb: class: cdc-wdm: switch to kfifo for buffering
config: arm-randconfig-004-20260504 (https://download.01.org/0day-ci/archive/20260504/202605042331.sI8rgflD-lkp@intel.com/config)
compiler: clang version 23.0.0git (https://github.com/llvm/llvm-project 5bac06718f502014fade905512f1d26d578a18f3)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260504/202605042331.sI8rgflD-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202605042331.sI8rgflD-lkp@intel.com/

All warnings (new ones prefixed by >>):

>> drivers/usb/class/cdc-wdm.c:526:6: warning: variable 'i' set but not used [-Wunused-but-set-variable]
     526 |         int i = 0;
         |             ^
   1 warning generated.


vim +/i +526 drivers/usb/class/cdc-wdm.c

8dd5cd5395b9007 Bjørn Mork          2013-12-20  521  
afba937e540c902 Oliver Neukum       2008-05-13  522  static ssize_t wdm_read
afba937e540c902 Oliver Neukum       2008-05-13  523  (struct file *file, char __user *buffer, size_t count, loff_t *ppos)
afba937e540c902 Oliver Neukum       2008-05-13  524  {
055e352971719f8 Oliver Neukum       2026-04-30  525  	int rv, cntr, done;
afba937e540c902 Oliver Neukum       2008-05-13 @526  	int i = 0;
afba937e540c902 Oliver Neukum       2008-05-13  527  	struct wdm_device *desc = file->private_data;
afba937e540c902 Oliver Neukum       2008-05-13  528  
afba937e540c902 Oliver Neukum       2008-05-13  529  
e8537bd2c4f325a Bjørn Mork          2012-01-16  530  	rv = mutex_lock_interruptible(&desc->rlock); /*concurrent reads */
afba937e540c902 Oliver Neukum       2008-05-13  531  	if (rv < 0)
afba937e540c902 Oliver Neukum       2008-05-13  532  		return -ERESTARTSYS;
afba937e540c902 Oliver Neukum       2008-05-13  533  
055e352971719f8 Oliver Neukum       2026-04-30  534  	cntr = kfifo_len(&desc->ubuf);
711c68b3c0f7a92 Ben Hutchings       2012-02-12  535  	if (cntr == 0) {
afba937e540c902 Oliver Neukum       2008-05-13  536  		desc->read = 0;
afba937e540c902 Oliver Neukum       2008-05-13  537  retry:
7f1dc313d01f5f0 Oliver Neukum       2009-09-09  538  		if (test_bit(WDM_DISCONNECTING, &desc->flags)) {
7f1dc313d01f5f0 Oliver Neukum       2009-09-09  539  			rv = -ENODEV;
7f1dc313d01f5f0 Oliver Neukum       2009-09-09  540  			goto err;
7f1dc313d01f5f0 Oliver Neukum       2009-09-09  541  		}
c0f5ecee4e74166 Oliver Neukum       2013-03-12  542  		if (test_bit(WDM_OVERFLOW, &desc->flags)) {
c0f5ecee4e74166 Oliver Neukum       2013-03-12  543  			clear_bit(WDM_OVERFLOW, &desc->flags);
c0f5ecee4e74166 Oliver Neukum       2013-03-12  544  			rv = -ENOBUFS;
c0f5ecee4e74166 Oliver Neukum       2013-03-12  545  			goto err;
c0f5ecee4e74166 Oliver Neukum       2013-03-12  546  		}
afba937e540c902 Oliver Neukum       2008-05-13  547  		i++;
7f1dc313d01f5f0 Oliver Neukum       2009-09-09  548  		if (file->f_flags & O_NONBLOCK) {
7f1dc313d01f5f0 Oliver Neukum       2009-09-09  549  			if (!test_bit(WDM_READ, &desc->flags)) {
53b7f7b53d83727 Gustavo A. R. Silva 2017-02-14  550  				rv = -EAGAIN;
7f1dc313d01f5f0 Oliver Neukum       2009-09-09  551  				goto err;
7f1dc313d01f5f0 Oliver Neukum       2009-09-09  552  			}
7f1dc313d01f5f0 Oliver Neukum       2009-09-09  553  			rv = 0;
7f1dc313d01f5f0 Oliver Neukum       2009-09-09  554  		} else {
afba937e540c902 Oliver Neukum       2008-05-13  555  			rv = wait_event_interruptible(desc->wait,
afba937e540c902 Oliver Neukum       2008-05-13  556  				test_bit(WDM_READ, &desc->flags));
7f1dc313d01f5f0 Oliver Neukum       2009-09-09  557  		}
afba937e540c902 Oliver Neukum       2008-05-13  558  
7f1dc313d01f5f0 Oliver Neukum       2009-09-09  559  		/* may have happened while we slept */
17d80d562fd78a0 Oliver Neukum       2008-06-24  560  		if (test_bit(WDM_DISCONNECTING, &desc->flags)) {
17d80d562fd78a0 Oliver Neukum       2008-06-24  561  			rv = -ENODEV;
17d80d562fd78a0 Oliver Neukum       2008-06-24  562  			goto err;
17d80d562fd78a0 Oliver Neukum       2008-06-24  563  		}
88044202756925a Bjørn Mork          2012-02-10  564  		if (test_bit(WDM_RESETTING, &desc->flags)) {
88044202756925a Bjørn Mork          2012-02-10  565  			rv = -EIO;
88044202756925a Bjørn Mork          2012-02-10  566  			goto err;
88044202756925a Bjørn Mork          2012-02-10  567  		}
055e352971719f8 Oliver Neukum       2026-04-30  568  		smp_rmb(); /* against wdm_in_callback() */
055e352971719f8 Oliver Neukum       2026-04-30  569  		if (test_bit(WDM_OVERFLOW, &desc->flags)) {
055e352971719f8 Oliver Neukum       2026-04-30  570  			clear_bit(WDM_OVERFLOW, &desc->flags);
055e352971719f8 Oliver Neukum       2026-04-30  571  			rv = -ENOBUFS;
055e352971719f8 Oliver Neukum       2026-04-30  572  			goto err;
055e352971719f8 Oliver Neukum       2026-04-30  573  		}
055e352971719f8 Oliver Neukum       2026-04-30  574  
17d80d562fd78a0 Oliver Neukum       2008-06-24  575  		usb_mark_last_busy(interface_to_usbdev(desc->intf));
afba937e540c902 Oliver Neukum       2008-05-13  576  		if (rv < 0) {
afba937e540c902 Oliver Neukum       2008-05-13  577  			rv = -ERESTARTSYS;
afba937e540c902 Oliver Neukum       2008-05-13  578  			goto err;
afba937e540c902 Oliver Neukum       2008-05-13  579  		}
afba937e540c902 Oliver Neukum       2008-05-13  580  
afba937e540c902 Oliver Neukum       2008-05-13  581  		spin_lock_irq(&desc->iuspin);
afba937e540c902 Oliver Neukum       2008-05-13  582  
afba937e540c902 Oliver Neukum       2008-05-13  583  		if (desc->rerr) { /* read completed, error happened */
85e8a0b9a3565c8 Oliver Neukum       2015-03-23  584  			rv = usb_translate_errors(desc->rerr);
afba937e540c902 Oliver Neukum       2008-05-13  585  			desc->rerr = 0;
afba937e540c902 Oliver Neukum       2008-05-13  586  			spin_unlock_irq(&desc->iuspin);
afba937e540c902 Oliver Neukum       2008-05-13  587  			goto err;
afba937e540c902 Oliver Neukum       2008-05-13  588  		}
afba937e540c902 Oliver Neukum       2008-05-13  589  		/*
afba937e540c902 Oliver Neukum       2008-05-13  590  		 * recheck whether we've lost the race
afba937e540c902 Oliver Neukum       2008-05-13  591  		 * against the completion handler
afba937e540c902 Oliver Neukum       2008-05-13  592  		 */
afba937e540c902 Oliver Neukum       2008-05-13  593  		if (!test_bit(WDM_READ, &desc->flags)) { /* lost race */
afba937e540c902 Oliver Neukum       2008-05-13  594  			spin_unlock_irq(&desc->iuspin);
afba937e540c902 Oliver Neukum       2008-05-13  595  			goto retry;
afba937e540c902 Oliver Neukum       2008-05-13  596  		}
c0f5ecee4e74166 Oliver Neukum       2013-03-12  597  
055e352971719f8 Oliver Neukum       2026-04-30  598  		cntr = kfifo_len(&desc->ubuf);
afba937e540c902 Oliver Neukum       2008-05-13  599  		spin_unlock_irq(&desc->iuspin);
afba937e540c902 Oliver Neukum       2008-05-13  600  	}
afba937e540c902 Oliver Neukum       2008-05-13  601  
711c68b3c0f7a92 Ben Hutchings       2012-02-12  602  	if (cntr > count)
711c68b3c0f7a92 Ben Hutchings       2012-02-12  603  		cntr = count;
055e352971719f8 Oliver Neukum       2026-04-30  604  	rv = kfifo_to_user(&desc->ubuf, buffer, cntr, &done);
055e352971719f8 Oliver Neukum       2026-04-30  605  	if (rv < 0) {
afba937e540c902 Oliver Neukum       2008-05-13  606  		rv = -EFAULT;
afba937e540c902 Oliver Neukum       2008-05-13  607  		goto err;
afba937e540c902 Oliver Neukum       2008-05-13  608  	}
afba937e540c902 Oliver Neukum       2008-05-13  609  
711c68b3c0f7a92 Ben Hutchings       2012-02-12  610  	spin_lock_irq(&desc->iuspin);
711c68b3c0f7a92 Ben Hutchings       2012-02-12  611  
87d65e54b6d5ff6 Oliver Neukum       2008-06-19  612  	/* in case we had outstanding data */
055e352971719f8 Oliver Neukum       2026-04-30  613  	if (kfifo_is_empty(&desc->ubuf)) {
c1da59dad0ebd3f Robert Foss         2016-08-09  614  		clear_bit(WDM_READ, &desc->flags);
c1da59dad0ebd3f Robert Foss         2016-08-09  615  		service_outstanding_interrupt(desc);
c1da59dad0ebd3f Robert Foss         2016-08-09  616  	}
73e06865ead1bec Greg Suarez         2013-10-29  617  	spin_unlock_irq(&desc->iuspin);
055e352971719f8 Oliver Neukum       2026-04-30  618  	rv = done;
afba937e540c902 Oliver Neukum       2008-05-13  619  
afba937e540c902 Oliver Neukum       2008-05-13  620  err:
e8537bd2c4f325a Bjørn Mork          2012-01-16  621  	mutex_unlock(&desc->rlock);
afba937e540c902 Oliver Neukum       2008-05-13  622  	return rv;
afba937e540c902 Oliver Neukum       2008-05-13  623  }
afba937e540c902 Oliver Neukum       2008-05-13  624  

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [RFT] usb: class: cdc-wdm: switch to kfifo for buffering
  2026-04-30 12:18 [RFT] usb: class: cdc-wdm: switch to kfifo for buffering Oliver Neukum
  2026-05-04 15:54 ` kernel test robot
@ 2026-05-04 20:37 ` kernel test robot
  1 sibling, 0 replies; 3+ messages in thread
From: kernel test robot @ 2026-05-04 20:37 UTC (permalink / raw)
  To: Oliver Neukum, hanguidong02, linux-usb; +Cc: llvm, oe-kbuild-all, Oliver Neukum

Hi Oliver,

kernel test robot noticed the following build warnings:

[auto build test WARNING on usb/usb-testing]
[also build test WARNING on usb/usb-next usb/usb-linus westeri-thunderbolt/next next-20260430]
[cannot apply to peter-chen-usb/for-usb-next linus/master v6.16-rc1]
[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#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Oliver-Neukum/usb-class-cdc-wdm-switch-to-kfifo-for-buffering/20260504-164851
base:   https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git usb-testing
patch link:    https://lore.kernel.org/r/20260430121859.1018894-1-oneukum%40suse.com
patch subject: [RFT] usb: class: cdc-wdm: switch to kfifo for buffering
config: x86_64-kexec (https://download.01.org/0day-ci/archive/20260504/202605042206.Ybpa1c91-lkp@intel.com/config)
compiler: clang version 20.1.8 (https://github.com/llvm/llvm-project 87f0227cb60147a26a1eeb4fb06e3b505e9c7261)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260504/202605042206.Ybpa1c91-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202605042206.Ybpa1c91-lkp@intel.com/

All warnings (new ones prefixed by >>):

>> drivers/usb/class/cdc-wdm.c:526:6: warning: variable 'i' set but not used [-Wunused-but-set-variable]
     526 |         int i = 0;
         |             ^
   1 warning generated.


vim +/i +526 drivers/usb/class/cdc-wdm.c

8dd5cd5395b900 Bjørn Mork          2013-12-20  521  
afba937e540c90 Oliver Neukum       2008-05-13  522  static ssize_t wdm_read
afba937e540c90 Oliver Neukum       2008-05-13  523  (struct file *file, char __user *buffer, size_t count, loff_t *ppos)
afba937e540c90 Oliver Neukum       2008-05-13  524  {
055e352971719f Oliver Neukum       2026-04-30  525  	int rv, cntr, done;
afba937e540c90 Oliver Neukum       2008-05-13 @526  	int i = 0;
afba937e540c90 Oliver Neukum       2008-05-13  527  	struct wdm_device *desc = file->private_data;
afba937e540c90 Oliver Neukum       2008-05-13  528  
afba937e540c90 Oliver Neukum       2008-05-13  529  
e8537bd2c4f325 Bjørn Mork          2012-01-16  530  	rv = mutex_lock_interruptible(&desc->rlock); /*concurrent reads */
afba937e540c90 Oliver Neukum       2008-05-13  531  	if (rv < 0)
afba937e540c90 Oliver Neukum       2008-05-13  532  		return -ERESTARTSYS;
afba937e540c90 Oliver Neukum       2008-05-13  533  
055e352971719f Oliver Neukum       2026-04-30  534  	cntr = kfifo_len(&desc->ubuf);
711c68b3c0f7a9 Ben Hutchings       2012-02-12  535  	if (cntr == 0) {
afba937e540c90 Oliver Neukum       2008-05-13  536  		desc->read = 0;
afba937e540c90 Oliver Neukum       2008-05-13  537  retry:
7f1dc313d01f5f Oliver Neukum       2009-09-09  538  		if (test_bit(WDM_DISCONNECTING, &desc->flags)) {
7f1dc313d01f5f Oliver Neukum       2009-09-09  539  			rv = -ENODEV;
7f1dc313d01f5f Oliver Neukum       2009-09-09  540  			goto err;
7f1dc313d01f5f Oliver Neukum       2009-09-09  541  		}
c0f5ecee4e7416 Oliver Neukum       2013-03-12  542  		if (test_bit(WDM_OVERFLOW, &desc->flags)) {
c0f5ecee4e7416 Oliver Neukum       2013-03-12  543  			clear_bit(WDM_OVERFLOW, &desc->flags);
c0f5ecee4e7416 Oliver Neukum       2013-03-12  544  			rv = -ENOBUFS;
c0f5ecee4e7416 Oliver Neukum       2013-03-12  545  			goto err;
c0f5ecee4e7416 Oliver Neukum       2013-03-12  546  		}
afba937e540c90 Oliver Neukum       2008-05-13  547  		i++;
7f1dc313d01f5f Oliver Neukum       2009-09-09  548  		if (file->f_flags & O_NONBLOCK) {
7f1dc313d01f5f Oliver Neukum       2009-09-09  549  			if (!test_bit(WDM_READ, &desc->flags)) {
53b7f7b53d8372 Gustavo A. R. Silva 2017-02-14  550  				rv = -EAGAIN;
7f1dc313d01f5f Oliver Neukum       2009-09-09  551  				goto err;
7f1dc313d01f5f Oliver Neukum       2009-09-09  552  			}
7f1dc313d01f5f Oliver Neukum       2009-09-09  553  			rv = 0;
7f1dc313d01f5f Oliver Neukum       2009-09-09  554  		} else {
afba937e540c90 Oliver Neukum       2008-05-13  555  			rv = wait_event_interruptible(desc->wait,
afba937e540c90 Oliver Neukum       2008-05-13  556  				test_bit(WDM_READ, &desc->flags));
7f1dc313d01f5f Oliver Neukum       2009-09-09  557  		}
afba937e540c90 Oliver Neukum       2008-05-13  558  
7f1dc313d01f5f Oliver Neukum       2009-09-09  559  		/* may have happened while we slept */
17d80d562fd78a Oliver Neukum       2008-06-24  560  		if (test_bit(WDM_DISCONNECTING, &desc->flags)) {
17d80d562fd78a Oliver Neukum       2008-06-24  561  			rv = -ENODEV;
17d80d562fd78a Oliver Neukum       2008-06-24  562  			goto err;
17d80d562fd78a Oliver Neukum       2008-06-24  563  		}
88044202756925 Bjørn Mork          2012-02-10  564  		if (test_bit(WDM_RESETTING, &desc->flags)) {
88044202756925 Bjørn Mork          2012-02-10  565  			rv = -EIO;
88044202756925 Bjørn Mork          2012-02-10  566  			goto err;
88044202756925 Bjørn Mork          2012-02-10  567  		}
055e352971719f Oliver Neukum       2026-04-30  568  		smp_rmb(); /* against wdm_in_callback() */
055e352971719f Oliver Neukum       2026-04-30  569  		if (test_bit(WDM_OVERFLOW, &desc->flags)) {
055e352971719f Oliver Neukum       2026-04-30  570  			clear_bit(WDM_OVERFLOW, &desc->flags);
055e352971719f Oliver Neukum       2026-04-30  571  			rv = -ENOBUFS;
055e352971719f Oliver Neukum       2026-04-30  572  			goto err;
055e352971719f Oliver Neukum       2026-04-30  573  		}
055e352971719f Oliver Neukum       2026-04-30  574  
17d80d562fd78a Oliver Neukum       2008-06-24  575  		usb_mark_last_busy(interface_to_usbdev(desc->intf));
afba937e540c90 Oliver Neukum       2008-05-13  576  		if (rv < 0) {
afba937e540c90 Oliver Neukum       2008-05-13  577  			rv = -ERESTARTSYS;
afba937e540c90 Oliver Neukum       2008-05-13  578  			goto err;
afba937e540c90 Oliver Neukum       2008-05-13  579  		}
afba937e540c90 Oliver Neukum       2008-05-13  580  
afba937e540c90 Oliver Neukum       2008-05-13  581  		spin_lock_irq(&desc->iuspin);
afba937e540c90 Oliver Neukum       2008-05-13  582  
afba937e540c90 Oliver Neukum       2008-05-13  583  		if (desc->rerr) { /* read completed, error happened */
85e8a0b9a3565c Oliver Neukum       2015-03-23  584  			rv = usb_translate_errors(desc->rerr);
afba937e540c90 Oliver Neukum       2008-05-13  585  			desc->rerr = 0;
afba937e540c90 Oliver Neukum       2008-05-13  586  			spin_unlock_irq(&desc->iuspin);
afba937e540c90 Oliver Neukum       2008-05-13  587  			goto err;
afba937e540c90 Oliver Neukum       2008-05-13  588  		}
afba937e540c90 Oliver Neukum       2008-05-13  589  		/*
afba937e540c90 Oliver Neukum       2008-05-13  590  		 * recheck whether we've lost the race
afba937e540c90 Oliver Neukum       2008-05-13  591  		 * against the completion handler
afba937e540c90 Oliver Neukum       2008-05-13  592  		 */
afba937e540c90 Oliver Neukum       2008-05-13  593  		if (!test_bit(WDM_READ, &desc->flags)) { /* lost race */
afba937e540c90 Oliver Neukum       2008-05-13  594  			spin_unlock_irq(&desc->iuspin);
afba937e540c90 Oliver Neukum       2008-05-13  595  			goto retry;
afba937e540c90 Oliver Neukum       2008-05-13  596  		}
c0f5ecee4e7416 Oliver Neukum       2013-03-12  597  
055e352971719f Oliver Neukum       2026-04-30  598  		cntr = kfifo_len(&desc->ubuf);
afba937e540c90 Oliver Neukum       2008-05-13  599  		spin_unlock_irq(&desc->iuspin);
afba937e540c90 Oliver Neukum       2008-05-13  600  	}
afba937e540c90 Oliver Neukum       2008-05-13  601  
711c68b3c0f7a9 Ben Hutchings       2012-02-12  602  	if (cntr > count)
711c68b3c0f7a9 Ben Hutchings       2012-02-12  603  		cntr = count;
055e352971719f Oliver Neukum       2026-04-30  604  	rv = kfifo_to_user(&desc->ubuf, buffer, cntr, &done);
055e352971719f Oliver Neukum       2026-04-30  605  	if (rv < 0) {
afba937e540c90 Oliver Neukum       2008-05-13  606  		rv = -EFAULT;
afba937e540c90 Oliver Neukum       2008-05-13  607  		goto err;
afba937e540c90 Oliver Neukum       2008-05-13  608  	}
afba937e540c90 Oliver Neukum       2008-05-13  609  
711c68b3c0f7a9 Ben Hutchings       2012-02-12  610  	spin_lock_irq(&desc->iuspin);
711c68b3c0f7a9 Ben Hutchings       2012-02-12  611  
87d65e54b6d5ff Oliver Neukum       2008-06-19  612  	/* in case we had outstanding data */
055e352971719f Oliver Neukum       2026-04-30  613  	if (kfifo_is_empty(&desc->ubuf)) {
c1da59dad0ebd3 Robert Foss         2016-08-09  614  		clear_bit(WDM_READ, &desc->flags);
c1da59dad0ebd3 Robert Foss         2016-08-09  615  		service_outstanding_interrupt(desc);
c1da59dad0ebd3 Robert Foss         2016-08-09  616  	}
73e06865ead1be Greg Suarez         2013-10-29  617  	spin_unlock_irq(&desc->iuspin);
055e352971719f Oliver Neukum       2026-04-30  618  	rv = done;
afba937e540c90 Oliver Neukum       2008-05-13  619  
afba937e540c90 Oliver Neukum       2008-05-13  620  err:
e8537bd2c4f325 Bjørn Mork          2012-01-16  621  	mutex_unlock(&desc->rlock);
afba937e540c90 Oliver Neukum       2008-05-13  622  	return rv;
afba937e540c90 Oliver Neukum       2008-05-13  623  }
afba937e540c90 Oliver Neukum       2008-05-13  624  

--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-05-04 20:38 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-30 12:18 [RFT] usb: class: cdc-wdm: switch to kfifo for buffering Oliver Neukum
2026-05-04 15:54 ` kernel test robot
2026-05-04 20:37 ` kernel test robot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox