1
0
Fork 0
mirror of synced 2025-03-06 20:59:54 +01:00

USB: serial: clean up throttle handling

Clean up the throttle implementation by dropping the redundant
throttle_req flag which was a remnant from back when there was only a
single read URB.

Also convert the throttled flag to an atomic bit flag.

Signed-off-by: Johan Hovold <johan@kernel.org>
This commit is contained in:
Johan Hovold 2019-04-25 18:05:37 +02:00
parent 3f5edd58d0
commit a8d78d9f38
2 changed files with 9 additions and 30 deletions

View file

@ -106,12 +106,8 @@ void usb_serial_generic_deregister(void)
int usb_serial_generic_open(struct tty_struct *tty, struct usb_serial_port *port) int usb_serial_generic_open(struct tty_struct *tty, struct usb_serial_port *port)
{ {
int result = 0; int result = 0;
unsigned long flags;
spin_lock_irqsave(&port->lock, flags); clear_bit(USB_SERIAL_THROTTLED, &port->flags);
port->throttled = 0;
port->throttle_req = 0;
spin_unlock_irqrestore(&port->lock, flags);
if (port->bulk_in_size) if (port->bulk_in_size)
result = usb_serial_generic_submit_read_urbs(port, GFP_KERNEL); result = usb_serial_generic_submit_read_urbs(port, GFP_KERNEL);
@ -375,7 +371,6 @@ void usb_serial_generic_read_bulk_callback(struct urb *urb)
{ {
struct usb_serial_port *port = urb->context; struct usb_serial_port *port = urb->context;
unsigned char *data = urb->transfer_buffer; unsigned char *data = urb->transfer_buffer;
unsigned long flags;
bool stopped = false; bool stopped = false;
int status = urb->status; int status = urb->status;
int i; int i;
@ -429,15 +424,10 @@ void usb_serial_generic_read_bulk_callback(struct urb *urb)
if (stopped) if (stopped)
return; return;
/* Throttle the device if requested by tty */ if (test_bit(USB_SERIAL_THROTTLED, &port->flags))
spin_lock_irqsave(&port->lock, flags); return;
port->throttled = port->throttle_req;
if (!port->throttled) { usb_serial_generic_submit_read_urb(port, i, GFP_ATOMIC);
spin_unlock_irqrestore(&port->lock, flags);
usb_serial_generic_submit_read_urb(port, i, GFP_ATOMIC);
} else {
spin_unlock_irqrestore(&port->lock, flags);
}
} }
EXPORT_SYMBOL_GPL(usb_serial_generic_read_bulk_callback); EXPORT_SYMBOL_GPL(usb_serial_generic_read_bulk_callback);
@ -485,23 +475,16 @@ EXPORT_SYMBOL_GPL(usb_serial_generic_write_bulk_callback);
void usb_serial_generic_throttle(struct tty_struct *tty) void usb_serial_generic_throttle(struct tty_struct *tty)
{ {
struct usb_serial_port *port = tty->driver_data; struct usb_serial_port *port = tty->driver_data;
unsigned long flags;
spin_lock_irqsave(&port->lock, flags); set_bit(USB_SERIAL_THROTTLED, &port->flags);
port->throttle_req = 1;
spin_unlock_irqrestore(&port->lock, flags);
} }
EXPORT_SYMBOL_GPL(usb_serial_generic_throttle); EXPORT_SYMBOL_GPL(usb_serial_generic_throttle);
void usb_serial_generic_unthrottle(struct tty_struct *tty) void usb_serial_generic_unthrottle(struct tty_struct *tty)
{ {
struct usb_serial_port *port = tty->driver_data; struct usb_serial_port *port = tty->driver_data;
int was_throttled;
spin_lock_irq(&port->lock); clear_bit(USB_SERIAL_THROTTLED, &port->flags);
was_throttled = port->throttled;
port->throttled = port->throttle_req = 0;
spin_unlock_irq(&port->lock);
/* /*
* Matches the smp_mb__after_atomic() in * Matches the smp_mb__after_atomic() in
@ -509,8 +492,7 @@ void usb_serial_generic_unthrottle(struct tty_struct *tty)
*/ */
smp_mb(); smp_mb();
if (was_throttled) usb_serial_generic_submit_read_urbs(port, GFP_KERNEL);
usb_serial_generic_submit_read_urbs(port, GFP_KERNEL);
} }
EXPORT_SYMBOL_GPL(usb_serial_generic_unthrottle); EXPORT_SYMBOL_GPL(usb_serial_generic_unthrottle);

View file

@ -28,6 +28,7 @@
/* USB serial flags */ /* USB serial flags */
#define USB_SERIAL_WRITE_BUSY 0 #define USB_SERIAL_WRITE_BUSY 0
#define USB_SERIAL_THROTTLED 1
/** /**
* usb_serial_port: structure for the specific ports of a device. * usb_serial_port: structure for the specific ports of a device.
@ -67,8 +68,6 @@
* @flags: usb serial port flags * @flags: usb serial port flags
* @write_wait: a wait_queue_head_t used by the port. * @write_wait: a wait_queue_head_t used by the port.
* @work: work queue entry for the line discipline waking up. * @work: work queue entry for the line discipline waking up.
* @throttled: nonzero if the read urb is inactive to throttle the device
* @throttle_req: nonzero if the tty wants to throttle us
* @dev: pointer to the serial device * @dev: pointer to the serial device
* *
* This structure is used by the usb-serial core and drivers for the specific * This structure is used by the usb-serial core and drivers for the specific
@ -115,8 +114,6 @@ struct usb_serial_port {
unsigned long flags; unsigned long flags;
wait_queue_head_t write_wait; wait_queue_head_t write_wait;
struct work_struct work; struct work_struct work;
char throttled;
char throttle_req;
unsigned long sysrq; /* sysrq timeout */ unsigned long sysrq; /* sysrq timeout */
struct device dev; struct device dev;
}; };