summaryrefslogtreecommitdiffstats
path: root/drivers/usb/class/cdc-acm.h
diff options
context:
space:
mode:
authorTim Chen <tim.c.chen@linux.intel.com>2026-09-21 17:37:22 -0700
committerIngo Molnar <mingo@kernel.org>2026-09-22 10:49:53 +0200
commit0d6526f82c3cdefcca47f73f5fc08dc6f335eac6 (patch)
tree176dc2d685debcfb082c151ee94f2425ac96b364 /drivers/usb/class/cdc-acm.h
downloadlinux-stable-0d6526f82c3cdefcca47f73f5fc08dc6f335eac6.tar.gz
linux-stable-0d6526f82c3cdefcca47f73f5fc08dc6f335eac6.zip
sched/cache: Keep nr_pref_llc_running in the runnable domain, to fix LLC mis-scheduling buggrafted
alb_break_llc() decides whether to break LLC preference during active load balance. It does so by testing that every runnable fair task on the source rq prefers its LLC: env->src_rq->nr_pref_llc_running == env->src_rq->cfs.h_nr_runnable But the two counters cover different sets. nr_pref_llc_running is updated in account_llc_enqueue()/account_llc_dequeue(), next to cfs_rq->nr_queued, so it follows queued tasks. h_nr_runnable is updated in set_delayed()/ clear_delayed() and drops delay-dequeued tasks. So under DELAY_DEQUEUE, a preferring task that goes to sleep stays counted in nr_pref_llc_running while h_nr_runnable falls. The equality then breaks, alb_break_llc() returns false, and active balance is free to pull a task off its preferred LLC. Active balance only moves runnable tasks, and this is the only LLC check it consults: once the stopper runs, LBF_ACTIVE_LB skips the per-task test in can_migrate_task(). The runnable set is the one we want. Fix it on the counter side. A task should be counted in nr_pref_llc_running exactly while it is both queued on its preferred LLC (pref_llc_queued) and runnable (!sched_delayed). Define that membership once in task_pref_llc_runnable(), and adjust the counter only through pref_llc_running_inc()/pref_llc_running_dec() from the four sites that change either input: account_llc_enqueue(), account_llc_dequeue(), set_delayed() and clear_delayed(). Gating every update on the same predicate keeps the delay, wake and dequeue paths from double-counting or underflowing; see the comments at those sites for the ordering. nr_llc_running and sd->llc_counts are not touched and stay on queued semantics. Fixes: 714059f79ff0 ("sched/cache: Handle moving single tasks to/from their preferred LLC") Closes: https://lore.kernel.org/lkml/20260827135000.735138-1-zhanxusheng@xiaomi.com/ Reported-by: Zhan Xusheng <zhanxusheng@xiaomi.com> Suggested-by: Chen Yu <yu.c.chen@intel.com> Signed-off-by: Tim Chen <tim.c.chen@linux.intel.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Reviewed-by: Kayra Cizmeci <kayracizmeci@gmail.com> Cc: <stable@kernel.org> # v7.2.x Link: https://patch.msgid.link/06af61afedac32e6477f57feb4d658f6c411c3af.1790035273.git.tim.c.chen@linux.intel.com
Diffstat (limited to 'drivers/usb/class/cdc-acm.h')
-rw-r--r--drivers/usb/class/cdc-acm.h119
1 files changed, 119 insertions, 0 deletions
diff --git a/drivers/usb/class/cdc-acm.h b/drivers/usb/class/cdc-acm.h
new file mode 100644
index 000000000..01f448a78
--- /dev/null
+++ b/drivers/usb/class/cdc-acm.h
@@ -0,0 +1,119 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ *
+ * Includes for cdc-acm.c
+ *
+ * Mainly take from usbnet's cdc-ether part
+ *
+ */
+
+/*
+ * Major and minor numbers.
+ */
+
+#define ACM_TTY_MAJOR 166
+#define ACM_TTY_MINORS 256
+
+#define ACM_MINOR_INVALID ACM_TTY_MINORS
+
+/*
+ * Requests.
+ */
+
+#define USB_RT_ACM (USB_TYPE_CLASS | USB_RECIP_INTERFACE)
+
+/*
+ * Internal driver structures.
+ */
+
+/*
+ * The only reason to have several buffers is to accommodate assumptions
+ * in line disciplines. They ask for empty space amount, receive our URB size,
+ * and proceed to issue several 1-character writes, assuming they will fit.
+ * The very first write takes a complete URB. Fortunately, this only happens
+ * when processing onlcr, so we only need 2 buffers. These values must be
+ * powers of 2.
+ */
+#define ACM_NW 16
+#define ACM_NR 16
+
+struct acm_wb {
+ u8 *buf;
+ dma_addr_t dmah;
+ unsigned int len;
+ struct urb *urb;
+ struct acm *instance;
+ bool use;
+};
+
+struct acm_rb {
+ int size;
+ unsigned char *base;
+ dma_addr_t dma;
+ int index;
+ struct acm *instance;
+};
+
+struct acm {
+ struct usb_device *dev; /* the corresponding usb device */
+ struct usb_interface *control; /* control interface */
+ struct usb_interface *data; /* data interface */
+ unsigned in, out; /* i/o pipes */
+ struct tty_port port; /* our tty port data */
+ struct urb *ctrlurb; /* urbs */
+ u8 *ctrl_buffer; /* buffers of urbs */
+ dma_addr_t ctrl_dma; /* dma handles of buffers */
+ u8 *country_codes; /* country codes from device */
+ unsigned int country_code_size; /* size of this buffer */
+ unsigned int country_rel_date; /* release date of version */
+ struct acm_wb wb[ACM_NW];
+ unsigned long read_urbs_free;
+ struct urb *read_urbs[ACM_NR];
+ struct acm_rb read_buffers[ACM_NR];
+ int rx_buflimit;
+ spinlock_t read_lock;
+ u8 *notification_buffer; /* to reassemble fragmented notifications */
+ unsigned int nb_index;
+ unsigned int nb_size;
+ int transmitting;
+ spinlock_t write_lock;
+ struct mutex mutex;
+ bool disconnected;
+ unsigned long flags;
+# define EVENT_TTY_WAKEUP 0
+# define EVENT_RX_STALL 1
+# define ACM_THROTTLED 2
+# define ACM_ERROR_DELAY 3
+ unsigned long urbs_in_error_delay; /* these need to be restarted after a delay */
+ struct usb_cdc_line_coding line; /* bits, stop, parity */
+ struct delayed_work dwork; /* work queue entry for various purposes */
+ unsigned int ctrlin; /* input control lines (DCD, DSR, RI, break, overruns) */
+ unsigned int ctrlout; /* output control lines (DTR, RTS) */
+ struct async_icount iocount; /* counters for control line changes */
+ struct async_icount oldcount; /* for comparison of counter */
+ wait_queue_head_t wioctl; /* for ioctl */
+ unsigned int writesize; /* max packet size for the output bulk endpoint */
+ unsigned int readsize,ctrlsize; /* buffer sizes for freeing */
+ unsigned int minor; /* acm minor number */
+ unsigned char clocal; /* termios CLOCAL */
+ unsigned int ctrl_caps; /* control capabilities from the class specific header */
+ unsigned int susp_count; /* number of suspended interfaces */
+ unsigned int combined_interfaces:1; /* control and data collapsed */
+ u8 bInterval;
+ struct usb_anchor delayed; /* writes queued for a device about to be woken */
+ unsigned long quirks;
+};
+
+/* constants describing various quirks and errors */
+#define NO_UNION_NORMAL BIT(0)
+#define SINGLE_RX_URB BIT(1)
+#define NO_CAP_LINE BIT(2)
+#define IGNORE_DEVICE BIT(3)
+#define QUIRK_CONTROL_LINE_STATE BIT(4)
+#define CLEAR_HALT_CONDITIONS BIT(5)
+#define SEND_ZERO_PACKET BIT(6)
+#define DISABLE_ECHO BIT(7)
+#define MISSING_CAP_BRK BIT(8)
+#define NO_UNION_12 BIT(9)
+#define VENDOR_CLASS_DATA_IFACE BIT(10) /* data interface uses vendor-specific class */
+#define ALWAYS_POLL_CTRL BIT(11) /* keep ctrl URB active even without an open TTY */