AI Trajectory


Trajectory: (Expand/Collapse All)
Seq Timestamp Type Name Duration
0/0 2026/08/01 07:55 flow patch-triage
1m Args:
null

Results:
{
  "EnableConfigs": [
    "TUN",
    "VHOST_NET"
  ],
  "FocusSymbols": [
    "tun_set_iff",
    "tun_queue_resize",
    "tun_attach",
    "tun_wake_queue"
  ],
  "Reasoning": "The patch introduces a new IFF_BACKPRESSURE flag for TUN/TAP devices, which modifies the queue handling logic in tun_net_xmit and vhost_net to stop the queue instead of dropping packets when the ring is full. This is a functional change in core networking and virtualization drivers that is reachable from user space via TUNSETIFF ioctl and network traffic, making it highly relevant for fuzzing.",
  "WorthFuzzing": true
}

1/1 2026/08/01 07:55 action read-patch-diff
0m Args:
null

Results:
{
  "PatchDiff": "commit 1d52293558ab52d2992610397c29ddbc8a12d0c5\nAuthor: syz-cluster \u003ctriage@syzkaller.com\u003e\nDate:   Sat Aug 1 07:55:50 2026 +0000\n\n    syz-cluster: applied patch under review\n\ndiff --git a/Documentation/networking/tuntap.rst b/Documentation/networking/tuntap.rst\nindex 4d7087f727be5..04155ef98e5bb 100644\n--- a/Documentation/networking/tuntap.rst\n+++ b/Documentation/networking/tuntap.rst\n@@ -206,6 +206,28 @@ enable is true we enable it, otherwise we disable it::\n       return ioctl(fd, TUNSETQUEUE, (void *)\u0026ifr);\n   }\n \n+3.4 qdisc backpressure\n+----------------------\n+\n+IFF_BACKPRESSURE can be set to enable qdisc backpressure. Without it, TX\n+drops occur when the internal ring buffer is full, so any attached qdisc\n+is effectively bypassed and applications only learn about congestion\n+through those drops.\n+\n+With it, the kernel stops instead, letting the qdisc hold and schedule\n+packets, so its AQM, shaping and fairness actually apply. This helps\n+protocols like TCP, which cut throughput in reaction to packet drops.\n+With IFF_BACKPRESSURE, drops then only occur as a rare race. Backpressure\n+requires a qdisc to be attached and has no effect with noqueue.\n+\n+The txqueuelen can be reduced alongside this flag to further shift\n+buffering into the qdisc and reduce bufferbloat, but comes at possible\n+performance cost.\n+\n+When running multiple network streams in parallel through a single\n+TUN/TAP queue, the flag may reduce performance due to the extra overhead\n+of the backpressure mechanism.\n+\n Universal TUN/TAP device driver Frequently Asked Question\n =========================================================\n \ndiff --git a/drivers/net/tun.c b/drivers/net/tun.c\nindex 51e80000bd0ed..5a927bbbda2f7 100644\n--- a/drivers/net/tun.c\n+++ b/drivers/net/tun.c\n@@ -98,7 +98,8 @@ static void tun_default_link_ksettings(struct net_device *dev,\n #define TUN_FASYNC\tIFF_ATTACH_QUEUE\n \n #define TUN_FEATURES (IFF_NO_PI | IFF_ONE_QUEUE | IFF_VNET_HDR | \\\n-\t\t      IFF_MULTI_QUEUE | IFF_NAPI | IFF_NAPI_FRAGS)\n+\t\t      IFF_MULTI_QUEUE | IFF_NAPI | IFF_NAPI_FRAGS | \\\n+\t\t      IFF_BACKPRESSURE)\n \n #define GOODCOPY_LEN 128\n \n@@ -145,6 +146,8 @@ struct tun_file {\n \tstruct list_head next;\n \tstruct tun_struct *detached;\n \tstruct ptr_ring tx_ring;\n+\t/* Protected by tx_ring.consumer_lock */\n+\tint cons_cnt;\n \tstruct xdp_rxq_info xdp_rxq;\n };\n \n@@ -588,8 +591,16 @@ static void __tun_detach(struct tun_file *tfile, bool clean)\n \t\trcu_assign_pointer(tun-\u003etfiles[index],\n \t\t\t\t   tun-\u003etfiles[tun-\u003enumqueues - 1]);\n \t\tntfile = rtnl_dereference(tun-\u003etfiles[index]);\n+\t\tspin_lock(\u0026ntfile-\u003etx_ring.consumer_lock);\n \t\tntfile-\u003equeue_index = index;\n \t\tntfile-\u003exdp_rxq.queue_index = index;\n+\t\tntfile-\u003econs_cnt = 0;\n+\t\t/* If the ring is not empty, the consumer wakes the queue\n+\t\t * after consuming the remaining entries.\n+\t\t */\n+\t\tif (__ptr_ring_empty(\u0026ntfile-\u003etx_ring))\n+\t\t\tnetif_wake_subqueue(tun-\u003edev, index);\n+\t\tspin_unlock(\u0026ntfile-\u003etx_ring.consumer_lock);\n \t\trcu_assign_pointer(tun-\u003etfiles[tun-\u003enumqueues - 1],\n \t\t\t\t   NULL);\n \n@@ -687,6 +698,20 @@ static void tun_detach_all(struct net_device *dev)\n \t\tmodule_put(THIS_MODULE);\n }\n \n+static void tun_force_wake_queue(struct tun_struct *tun,\n+\t\t\t\t struct tun_file *tfile)\n+{\n+\t/* Ensure that the producer can not stop the\n+\t * queue concurrently by taking locks.\n+\t */\n+\tspin_lock_bh(\u0026tfile-\u003etx_ring.consumer_lock);\n+\tspin_lock(\u0026tfile-\u003etx_ring.producer_lock);\n+\tnetif_wake_subqueue(tun-\u003edev, tfile-\u003equeue_index);\n+\ttfile-\u003econs_cnt = 0;\n+\tspin_unlock(\u0026tfile-\u003etx_ring.producer_lock);\n+\tspin_unlock_bh(\u0026tfile-\u003etx_ring.consumer_lock);\n+}\n+\n static int tun_attach(struct tun_struct *tun, struct file *file,\n \t\t      bool skip_filter, bool napi, bool napi_frags,\n \t\t      bool publish_tun)\n@@ -732,6 +757,7 @@ static int tun_attach(struct tun_struct *tun, struct file *file,\n \n \ttfile-\u003equeue_index = tun-\u003enumqueues;\n \ttfile-\u003esocket.sk-\u003esk_shutdown \u0026= ~RCV_SHUTDOWN;\n+\ttun_force_wake_queue(tun, tfile);\n \n \tif (tfile-\u003edetached) {\n \t\t/* Re-attach detached tfile, updating XDP queue_index */\n@@ -1008,6 +1034,7 @@ static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev)\n \tstruct netdev_queue *queue;\n \tstruct tun_file *tfile;\n \tint len = skb-\u003elen;\n+\tint ret;\n \n \trcu_read_lock();\n \ttfile = rcu_dereference(tun-\u003etfiles[txq]);\n@@ -1062,13 +1089,34 @@ static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev)\n \n \tnf_reset_ct(skb);\n \n-\tif (ptr_ring_produce(\u0026tfile-\u003etx_ring, skb)) {\n+\tqueue = netdev_get_tx_queue(dev, txq);\n+\n+\tspin_lock(\u0026tfile-\u003etx_ring.producer_lock);\n+\tret = __ptr_ring_produce(\u0026tfile-\u003etx_ring, skb);\n+\tif ((tun-\u003eflags \u0026 IFF_BACKPRESSURE) \u0026\u0026\n+\t    !qdisc_txq_has_no_queue(queue) \u0026\u0026\n+\t    __ptr_ring_check_produce(\u0026tfile-\u003etx_ring) == -ENOSPC) {\n+\t\tnetif_tx_stop_queue(queue);\n+\t\t/* Paired with smp_mb() in __tun_wake_queue() */\n+\t\tsmp_mb__after_atomic();\n+\t\tif (!__ptr_ring_check_produce(\u0026tfile-\u003etx_ring))\n+\t\t\tnetif_tx_wake_queue(queue);\n+\t}\n+\tspin_unlock(\u0026tfile-\u003etx_ring.producer_lock);\n+\n+\tif (ret) {\n+\t\t/* This should be a rare case if IFF_BACKPRESSURE is enabled and\n+\t\t * a qdisc is present, but can happen due to lltx.\n+\t\t * Since skb_tx_timestamp(), skb_orphan(),\n+\t\t * run_ebpf_filter() and pskb_trim() could have tinkered\n+\t\t * with the SKB, returning NETDEV_TX_BUSY is unsafe and\n+\t\t * we must drop instead.\n+\t\t */\n \t\tdrop_reason = SKB_DROP_REASON_FULL_RING;\n \t\tgoto drop;\n \t}\n \n \t/* dev-\u003elltx requires to do our own update of trans_start */\n-\tqueue = netdev_get_tx_queue(dev, txq);\n \ttxq_trans_cond_update(queue);\n \n \t/* Notify and wake up reader process */\n@@ -2116,13 +2164,50 @@ static ssize_t tun_put_user(struct tun_struct *tun,\n \treturn total;\n }\n \n-static void *tun_ring_recv(struct tun_file *tfile, int noblock, int *err)\n+/* Callers must hold ring.consumer_lock */\n+static void __tun_wake_queue(struct tun_struct *tun,\n+\t\t\t     struct tun_file *tfile, int consumed)\n+{\n+\tstruct netdev_queue *txq;\n+\n+\tif (!(tun-\u003eflags \u0026 IFF_BACKPRESSURE))\n+\t\treturn;\n+\n+\ttxq = netdev_get_tx_queue(tun-\u003edev, tfile-\u003equeue_index);\n+\n+\t/* Paired with smp_mb__after_atomic() in tun_net_xmit() */\n+\tsmp_mb();\n+\tif (netif_tx_queue_stopped(txq)) {\n+\t\ttfile-\u003econs_cnt += consumed;\n+\t\tif (tfile-\u003econs_cnt \u003e= tfile-\u003etx_ring.size / 2 ||\n+\t\t    __ptr_ring_empty(\u0026tfile-\u003etx_ring)) {\n+\t\t\tnetif_tx_wake_queue(txq);\n+\t\t\ttfile-\u003econs_cnt = 0;\n+\t\t}\n+\t}\n+}\n+\n+static void *tun_ring_consume(struct tun_struct *tun, struct tun_file *tfile)\n+{\n+\tvoid *ptr;\n+\n+\tspin_lock(\u0026tfile-\u003etx_ring.consumer_lock);\n+\tptr = __ptr_ring_consume(\u0026tfile-\u003etx_ring);\n+\tif (ptr)\n+\t\t__tun_wake_queue(tun, tfile, 1);\n+\n+\tspin_unlock(\u0026tfile-\u003etx_ring.consumer_lock);\n+\treturn ptr;\n+}\n+\n+static void *tun_ring_recv(struct tun_struct *tun, struct tun_file *tfile,\n+\t\t\t   int noblock, int *err)\n {\n \tDECLARE_WAITQUEUE(wait, current);\n \tvoid *ptr = NULL;\n \tint error = 0;\n \n-\tptr = ptr_ring_consume(\u0026tfile-\u003etx_ring);\n+\tptr = tun_ring_consume(tun, tfile);\n \tif (ptr)\n \t\tgoto out;\n \tif (noblock) {\n@@ -2134,7 +2219,7 @@ static void *tun_ring_recv(struct tun_file *tfile, int noblock, int *err)\n \n \twhile (1) {\n \t\tset_current_state(TASK_INTERRUPTIBLE);\n-\t\tptr = ptr_ring_consume(\u0026tfile-\u003etx_ring);\n+\t\tptr = tun_ring_consume(tun, tfile);\n \t\tif (ptr)\n \t\t\tbreak;\n \t\tif (signal_pending(current)) {\n@@ -2171,7 +2256,7 @@ static ssize_t tun_do_read(struct tun_struct *tun, struct tun_file *tfile,\n \n \tif (!ptr) {\n \t\t/* Read frames from ring */\n-\t\tptr = tun_ring_recv(tfile, noblock, \u0026err);\n+\t\tptr = tun_ring_recv(tun, tfile, noblock, \u0026err);\n \t\tif (!ptr)\n \t\t\treturn err;\n \t}\n@@ -2704,7 +2789,7 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)\n \tstruct tun_struct *tun;\n \tstruct tun_file *tfile = file-\u003eprivate_data;\n \tstruct net_device *dev;\n-\tint err;\n+\tint err, i;\n \n \tif (tfile-\u003edetached)\n \t\treturn -EINVAL;\n@@ -2833,8 +2918,12 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)\n \t/* Make sure persistent devices do not get stuck in\n \t * xoff state.\n \t */\n-\tif (netif_running(tun-\u003edev))\n-\t\tnetif_tx_wake_all_queues(tun-\u003edev);\n+\tif (netif_running(tun-\u003edev)) {\n+\t\tfor (i = 0; i \u003c tun-\u003enumqueues; i++) {\n+\t\t\ttfile = rtnl_dereference(tun-\u003etfiles[i]);\n+\t\t\ttun_force_wake_queue(tun, tfile);\n+\t\t}\n+\t}\n \n \tstrscpy(ifr-\u003eifr_name, tun-\u003edev-\u003ename);\n \treturn 0;\n@@ -3630,6 +3719,13 @@ static int tun_queue_resize(struct tun_struct *tun)\n \t\t\t\t\t  dev-\u003etx_queue_len, GFP_KERNEL,\n \t\t\t\t\t  tun_ptr_free);\n \n+\tif (!ret) {\n+\t\tfor (i = 0; i \u003c tun-\u003enumqueues; i++) {\n+\t\t\ttfile = rtnl_dereference(tun-\u003etfiles[i]);\n+\t\t\ttun_force_wake_queue(tun, tfile);\n+\t\t}\n+\t}\n+\n \tkfree(rings);\n \treturn ret;\n }\n@@ -3738,6 +3834,29 @@ struct ptr_ring *tun_get_tx_ring(struct file *file)\n }\n EXPORT_SYMBOL_GPL(tun_get_tx_ring);\n \n+/* Callers must hold ring.consumer_lock */\n+void tun_wake_queue(struct file *file, int consumed)\n+{\n+\tstruct tun_file *tfile;\n+\tstruct tun_struct *tun;\n+\n+\tif (file-\u003ef_op != \u0026tun_fops)\n+\t\treturn;\n+\n+\ttfile = file-\u003eprivate_data;\n+\tif (!tfile)\n+\t\treturn;\n+\n+\trcu_read_lock();\n+\n+\ttun = rcu_dereference(tfile-\u003etun);\n+\tif (tun)\n+\t\t__tun_wake_queue(tun, tfile, consumed);\n+\n+\trcu_read_unlock();\n+}\n+EXPORT_SYMBOL_GPL(tun_wake_queue);\n+\n module_init(tun_init);\n module_exit(tun_cleanup);\n MODULE_DESCRIPTION(DRV_DESCRIPTION);\ndiff --git a/drivers/vhost/net.c b/drivers/vhost/net.c\nindex 6949b704166d5..3e72b9c6af0ca 100644\n--- a/drivers/vhost/net.c\n+++ b/drivers/vhost/net.c\n@@ -176,13 +176,21 @@ static void *vhost_net_buf_consume(struct vhost_net_buf *rxq)\n \treturn ret;\n }\n \n-static int vhost_net_buf_produce(struct vhost_net_virtqueue *nvq)\n+static int vhost_net_buf_produce(struct sock *sk,\n+\t\t\t\t struct vhost_net_virtqueue *nvq)\n {\n+\tstruct file *file = sk-\u003esk_socket-\u003efile;\n \tstruct vhost_net_buf *rxq = \u0026nvq-\u003erxq;\n \n \trxq-\u003ehead = 0;\n-\trxq-\u003etail = ptr_ring_consume_batched(nvq-\u003erx_ring, rxq-\u003equeue,\n-\t\t\t\t\t      VHOST_NET_BATCH);\n+\tspin_lock(\u0026nvq-\u003erx_ring-\u003econsumer_lock);\n+\trxq-\u003etail = __ptr_ring_consume_batched(nvq-\u003erx_ring, rxq-\u003equeue,\n+\t\t\t\t\t       VHOST_NET_BATCH);\n+\n+\tif (rxq-\u003etail)\n+\t\ttun_wake_queue(file, rxq-\u003etail);\n+\n+\tspin_unlock(\u0026nvq-\u003erx_ring-\u003econsumer_lock);\n \treturn rxq-\u003etail;\n }\n \n@@ -209,14 +217,15 @@ static int vhost_net_buf_peek_len(void *ptr)\n \treturn __skb_array_len_with_tag(ptr);\n }\n \n-static int vhost_net_buf_peek(struct vhost_net_virtqueue *nvq)\n+static int vhost_net_buf_peek(struct sock *sk,\n+\t\t\t      struct vhost_net_virtqueue *nvq)\n {\n \tstruct vhost_net_buf *rxq = \u0026nvq-\u003erxq;\n \n \tif (!vhost_net_buf_is_empty(rxq))\n \t\tgoto out;\n \n-\tif (!vhost_net_buf_produce(nvq))\n+\tif (!vhost_net_buf_produce(sk, nvq))\n \t\treturn 0;\n \n out:\n@@ -1004,7 +1013,7 @@ static int peek_head_len(struct vhost_net_virtqueue *rvq, struct sock *sk)\n \tunsigned long flags;\n \n \tif (rvq-\u003erx_ring)\n-\t\treturn vhost_net_buf_peek(rvq);\n+\t\treturn vhost_net_buf_peek(sk, rvq);\n \n \tspin_lock_irqsave(\u0026sk-\u003esk_receive_queue.lock, flags);\n \thead = skb_peek(\u0026sk-\u003esk_receive_queue);\ndiff --git a/include/linux/if_tun.h b/include/linux/if_tun.h\nindex 80166eb62f41c..5f3e206c7a737 100644\n--- a/include/linux/if_tun.h\n+++ b/include/linux/if_tun.h\n@@ -22,6 +22,7 @@ struct tun_msg_ctl {\n #if defined(CONFIG_TUN) || defined(CONFIG_TUN_MODULE)\n struct socket *tun_get_socket(struct file *);\n struct ptr_ring *tun_get_tx_ring(struct file *file);\n+void tun_wake_queue(struct file *file, int consumed);\n \n static inline bool tun_is_xdp_frame(void *ptr)\n {\n@@ -55,6 +56,8 @@ static inline struct ptr_ring *tun_get_tx_ring(struct file *f)\n \treturn ERR_PTR(-EINVAL);\n }\n \n+static inline void tun_wake_queue(struct file *f, int consumed) {}\n+\n static inline bool tun_is_xdp_frame(void *ptr)\n {\n \treturn false;\ndiff --git a/include/linux/ptr_ring.h b/include/linux/ptr_ring.h\nindex d2c3629bbe451..c95e891903f05 100644\n--- a/include/linux/ptr_ring.h\n+++ b/include/linux/ptr_ring.h\n@@ -96,6 +96,20 @@ static inline bool ptr_ring_full_bh(struct ptr_ring *r)\n \treturn ret;\n }\n \n+/* Note: callers invoking this in a loop must use a compiler barrier,\n+ * for example cpu_relax(). Callers must hold producer_lock.\n+ */\n+static inline int __ptr_ring_check_produce(struct ptr_ring *r)\n+{\n+\tif (unlikely(!r-\u003esize))\n+\t\treturn -EINVAL;\n+\n+\tif (data_race(r-\u003equeue[r-\u003eproducer]))\n+\t\treturn -ENOSPC;\n+\n+\treturn 0;\n+}\n+\n /* Note: callers invoking this in a loop must use a compiler barrier,\n  * for example cpu_relax(). Callers must hold producer_lock.\n  * Callers are responsible for making sure pointer that is being queued\n@@ -103,8 +117,10 @@ static inline bool ptr_ring_full_bh(struct ptr_ring *r)\n  */\n static inline int __ptr_ring_produce(struct ptr_ring *r, void *ptr)\n {\n-\tif (unlikely(!r-\u003esize) || data_race(r-\u003equeue[r-\u003eproducer]))\n-\t\treturn -ENOSPC;\n+\tint p = __ptr_ring_check_produce(r);\n+\n+\tif (p)\n+\t\treturn p;\n \n \t/* Make sure the pointer we are storing points to a valid data. */\n \t/* Pairs with the dependency ordering in __ptr_ring_consume. */\ndiff --git a/include/uapi/linux/if_tun.h b/include/uapi/linux/if_tun.h\nindex 79d53c7a1ebdc..a0ddc50a75342 100644\n--- a/include/uapi/linux/if_tun.h\n+++ b/include/uapi/linux/if_tun.h\n@@ -69,6 +69,10 @@\n #define IFF_NAPI_FRAGS\t0x0020\n /* Used in TUNSETIFF to bring up tun/tap without carrier */\n #define IFF_NO_CARRIER\t0x0040\n+/* Stop the queue instead of dropping when the internal ring is full, so an\n+ * attached qdisc applies backpressure instead of being bypassed.\n+ */\n+#define IFF_BACKPRESSURE\t0x0080\n #define IFF_NO_PI\t0x1000\n /* This flag has no real effect */\n #define IFF_ONE_QUEUE\t0x2000\ndiff --git a/tools/include/uapi/linux/if_tun.h b/tools/include/uapi/linux/if_tun.h\nindex 2ec07de1d73be..2c85525704c16 100644\n--- a/tools/include/uapi/linux/if_tun.h\n+++ b/tools/include/uapi/linux/if_tun.h\n@@ -67,6 +67,10 @@\n #define IFF_TAP\t\t0x0002\n #define IFF_NAPI\t0x0010\n #define IFF_NAPI_FRAGS\t0x0020\n+/* Stop the queue instead of dropping when the internal ring is full, so an\n+ * attached qdisc applies backpressure instead of being bypassed.\n+ */\n+#define IFF_BACKPRESSURE\t0x0080\n #define IFF_NO_PI\t0x1000\n /* This flag has no real effect */\n #define IFF_ONE_QUEUE\t0x2000\n"
}

2/1 2026/08/01 07:55 agent patch-evaluator
1m Model:
best-expensive

Args:
null

Results:
{
  "EnableConfigs": [
    "TUN",
    "VHOST_NET"
  ],
  "FocusSymbols": [
    "tun_set_iff",
    "tun_queue_resize",
    "tun_attach",
    "tun_wake_queue"
  ],
  "Reasoning": "The patch introduces a new IFF_BACKPRESSURE flag for TUN/TAP devices, which modifies the queue handling logic in tun_net_xmit and vhost_net to stop the queue instead of dropping packets when the ring is full. This is a functional change in core networking and virtualization drivers that is reachable from user space via TUNSETIFF ioctl and network traffic, making it highly relevant for fuzzing.",
  "WorthFuzzing": true
}

Instruction:
You are an expert Linux kernel maintainer.
Your job is to review a provided patch series and determine
if it makes functional changes to the kernel that should be fuzzed.

IMPORTANT: The changes have ALREADY been applied and committed as the HEAD commit in
your workspace. Do NOT rely on your internal knowledge of the kernel. You must actively
use your code access tools to examine the actual source code and confirm any assumptions.

Return WorthFuzzing=false if the patch only contains:
- Modifications to Documentation/, Kconfig files, or code comments.
- Purely decorative changes, such as logging (e.g., pr_err, printk) or tracepoints.
- Changes to numeric constants or macros that do not functionally alter execution flow.
- Code paths that are impossible to reach in virtualized environments like GCE or QEMU,
  even when utilizing software-emulated hardware (e.g., usb gadget, mac80211_hwsim).
- Code in vendor-specific PCIe switch, SmartNIC, or GPU drivers (e.g., mlxsw, pds_core, qed,
  ionic, amdgpu) that require physical PCIe hardware cards not emulated in standard QEMU.
- Driver .remove, .shutdown, or pci_unregister_driver teardown callbacks (e.g., igb_remove)
  that are executed only during PCI hot-unplug or sysfs driver unbind operations.

If it modifies reachable core kernel logic, drivers, or architectures, use your code search
tools to verify the code can be executed, then return WorthFuzzing=true.

When returning WorthFuzzing=true, you MUST ALSO:
1. Extract any specific kernel functions that should be heavily fuzzed into FocusSymbols.
   Avoid listing generic hot-path functions to prevent skewed test distributions.
   Prefer non-static, non-inlined API entrypoint functions over internal static helper functions
   (which are inlined by the compiler and do not have distinct symbol addresses).
2. Identify any specific CONFIG_ options required to properly test this new/modified feature.
   Go and look into the Kconfig files and check for ifdefs around the code, do not make assumptions.
   Also check "depends on" lines in Kconfig to include any non-standard parent subsystem configs
   needed for Kbuild to compile the code statically into vmlinux. List them in the EnableConfigs
   output array, and DO NOT add a 'CONFIG_' prefix (e.g., return "NET_IPV4" instead of "CONFIG_NET_IPV4").
Prefer calling several tools at the same time to save round-trips.


Use set-results tool to provide results of the analysis.
It must be called exactly once before the final reply.
Ignore results of this tool.

Prompt:
For your convenience, here is the diff of the changes:
commit 1d52293558ab52d2992610397c29ddbc8a12d0c5
Author: syz-cluster <triage@syzkaller.com>
Date:   Sat Aug 1 07:55:50 2026 +0000

    syz-cluster: applied patch under review

diff --git a/Documentation/networking/tuntap.rst b/Documentation/networking/tuntap.rst
index 4d7087f727be5..04155ef98e5bb 100644
--- a/Documentation/networking/tuntap.rst
+++ b/Documentation/networking/tuntap.rst
@@ -206,6 +206,28 @@ enable is true we enable it, otherwise we disable it::
       return ioctl(fd, TUNSETQUEUE, (void *)&ifr);
   }
 
+3.4 qdisc backpressure
+----------------------
+
+IFF_BACKPRESSURE can be set to enable qdisc backpressure. Without it, TX
+drops occur when the internal ring buffer is full, so any attached qdisc
+is effectively bypassed and applications only learn about congestion
+through those drops.
+
+With it, the kernel stops instead, letting the qdisc hold and schedule
+packets, so its AQM, shaping and fairness actually apply. This helps
+protocols like TCP, which cut throughput in reaction to packet drops.
+With IFF_BACKPRESSURE, drops then only occur as a rare race. Backpressure
+requires a qdisc to be attached and has no effect with noqueue.
+
+The txqueuelen can be reduced alongside this flag to further shift
+buffering into the qdisc and reduce bufferbloat, but comes at possible
+performance cost.
+
+When running multiple network streams in parallel through a single
+TUN/TAP queue, the flag may reduce performance due to the extra overhead
+of the backpressure mechanism.
+
 Universal TUN/TAP device driver Frequently Asked Question
 =========================================================
 
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 51e80000bd0ed..5a927bbbda2f7 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -98,7 +98,8 @@ static void tun_default_link_ksettings(struct net_device *dev,
 #define TUN_FASYNC	IFF_ATTACH_QUEUE
 
 #define TUN_FEATURES (IFF_NO_PI | IFF_ONE_QUEUE | IFF_VNET_HDR | \
-		      IFF_MULTI_QUEUE | IFF_NAPI | IFF_NAPI_FRAGS)
+		      IFF_MULTI_QUEUE | IFF_NAPI | IFF_NAPI_FRAGS | \
+		      IFF_BACKPRESSURE)
 
 #define GOODCOPY_LEN 128
 
@@ -145,6 +146,8 @@ struct tun_file {
 	struct list_head next;
 	struct tun_struct *detached;
 	struct ptr_ring tx_ring;
+	/* Protected by tx_ring.consumer_lock */
+	int cons_cnt;
 	struct xdp_rxq_info xdp_rxq;
 };
 
@@ -588,8 +591,16 @@ static void __tun_detach(struct tun_file *tfile, bool clean)
 		rcu_assign_pointer(tun->tfiles[index],
 				   tun->tfiles[tun->numqueues - 1]);
 		ntfile = rtnl_dereference(tun->tfiles[index]);
+		spin_lock(&ntfile->tx_ring.consumer_lock);
 		ntfile->queue_index = index;
 		ntfile->xdp_rxq.queue_index = index;
+		ntfile->cons_cnt = 0;
+		/* If the ring is not empty, the consumer wakes the queue
+		 * after consuming the remaining entries.
+		 */
+		if (__ptr_ring_empty(&ntfile->tx_ring))
+			netif_wake_subqueue(tun->dev, index);
+		spin_unlock(&ntfile->tx_ring.consumer_lock);
 		rcu_assign_pointer(tun->tfiles[tun->numqueues - 1],
 				   NULL);
 
@@ -687,6 +698,20 @@ static void tun_detach_all(struct net_device *dev)
 		module_put(THIS_MODULE);
 }
 
+static void tun_force_wake_queue(struct tun_struct *tun,
+				 struct tun_file *tfile)
+{
+	/* Ensure that the producer can not stop the
+	 * queue concurrently by taking locks.
+	 */
+	spin_lock_bh(&tfile->tx_ring.consumer_lock);
+	spin_lock(&tfile->tx_ring.producer_lock);
+	netif_wake_subqueue(tun->dev, tfile->queue_index);
+	tfile->cons_cnt = 0;
+	spin_unlock(&tfile->tx_ring.producer_lock);
+	spin_unlock_bh(&tfile->tx_ring.consumer_lock);
+}
+
 static int tun_attach(struct tun_struct *tun, struct file *file,
 		      bool skip_filter, bool napi, bool napi_frags,
 		      bool publish_tun)
@@ -732,6 +757,7 @@ static int tun_attach(struct tun_struct *tun, struct file *file,
 
 	tfile->queue_index = tun->numqueues;
 	tfile->socket.sk->sk_shutdown &= ~RCV_SHUTDOWN;
+	tun_force_wake_queue(tun, tfile);
 
 	if (tfile->detached) {
 		/* Re-attach detached tfile, updating XDP queue_index */
@@ -1008,6 +1034,7 @@ static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev)
 	struct netdev_queue *queue;
 	struct tun_file *tfile;
 	int len = skb->len;
+	int ret;
 
 	rcu_read_lock();
 	tfile = rcu_dereference(tun->tfiles[txq]);
@@ -1062,13 +1089,34 @@ static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev)
 
 	nf_reset_ct(skb);
 
-	if (ptr_ring_produce(&tfile->tx_ring, skb)) {
+	queue = netdev_get_tx_queue(dev, txq);
+
+	spin_lock(&tfile->tx_ring.producer_lock);
+	ret = __ptr_ring_produce(&tfile->tx_ring, skb);
+	if ((tun->flags & IFF_BACKPRESSURE) &&
+	    !qdisc_txq_has_no_queue(queue) &&
+	    __ptr_ring_check_produce(&tfile->tx_ring) == -ENOSPC) {
+		netif_tx_stop_queue(queue);
+		/* Paired with smp_mb() in __tun_wake_queue() */
+		smp_mb__after_atomic();
+		if (!__ptr_ring_check_produce(&tfile->tx_ring))
+			netif_tx_wake_queue(queue);
+	}
+	spin_unlock(&tfile->tx_ring.producer_lock);
+
+	if (ret) {
+		/* This should be a rare case if IFF_BACKPRESSURE is enabled and
+		 * a qdisc is present, but can happen due to lltx.
+		 * Since skb_tx_timestamp(), skb_orphan(),
+		 * run_ebpf_filter() and pskb_trim() could have tinkered
+		 * with the SKB, returning NETDEV_TX_BUSY is unsafe and
+		 * we must drop instead.
+		 */
 		drop_reason = SKB_DROP_REASON_FULL_RING;
 		goto drop;
 	}
 
 	/* dev->lltx requires to do our own update of trans_start */
-	queue = netdev_get_tx_queue(dev, txq);
 	txq_trans_cond_update(queue);
 
 	/* Notify and wake up reader process */
@@ -2116,13 +2164,50 @@ static ssize_t tun_put_user(struct tun_struct *tun,
 	return total;
 }
 
-static void *tun_ring_recv(struct tun_file *tfile, int noblock, int *err)
+/* Callers must hold ring.consumer_lock */
+static void __tun_wake_queue(struct tun_struct *tun,
+			     struct tun_file *tfile, int consumed)
+{
+	struct netdev_queue *txq;
+
+	if (!(tun->flags & IFF_BACKPRESSURE))
+		return;
+
+	txq = netdev_get_tx_queue(tun->dev, tfile->queue_index);
+
+	/* Paired with smp_mb__after_atomic() in tun_net_xmit() */
+	smp_mb();
+	if (netif_tx_queue_stopped(txq)) {
+		tfile->cons_cnt += consumed;
+		if (tfile->cons_cnt >= tfile->tx_ring.size / 2 ||
+		    __ptr_ring_empty(&tfile->tx_ring)) {
+			netif_tx_wake_queue(txq);
+			tfile->cons_cnt = 0;
+		}
+	}
+}
+
+static void *tun_ring_consume(struct tun_struct *tun, struct tun_file *tfile)
+{
+	void *ptr;
+
+	spin_lock(&tfile->tx_ring.consumer_lock);
+	ptr = __ptr_ring_consume(&tfile->tx_ring);
+	if (ptr)
+		__tun_wake_queue(tun, tfile, 1);
+
+	spin_unlock(&tfile->tx_ring.consumer_lock);
+	return ptr;
+}
+
+static void *tun_ring_recv(struct tun_struct *tun, struct tun_file *tfile,
+			   int noblock, int *err)
 {
 	DECLARE_WAITQUEUE(wait, current);
 	void *ptr = NULL;
 	int error = 0;
 
-	ptr = ptr_ring_consume(&tfile->tx_ring);
+	ptr = tun_ring_consume(tun, tfile);
 	if (ptr)
 		goto out;
 	if (noblock) {
@@ -2134,7 +2219,7 @@ static void *tun_ring_recv(struct tun_file *tfile, int noblock, int *err)
 
 	while (1) {
 		set_current_state(TASK_INTERRUPTIBLE);
-		ptr = ptr_ring_consume(&tfile->tx_ring);
+		ptr = tun_ring_consume(tun, tfile);
 		if (ptr)
 			break;
 		if (signal_pending(current)) {
@@ -2171,7 +2256,7 @@ static ssize_t tun_do_read(struct tun_struct *tun, struct tun_file *tfile,
 
 	if (!ptr) {
 		/* Read frames from ring */
-		ptr = tun_ring_recv(tfile, noblock, &err);
+		ptr = tun_ring_recv(tun, tfile, noblock, &err);
 		if (!ptr)
 			return err;
 	}
@@ -2704,7 +2789,7 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
 	struct tun_struct *tun;
 	struct tun_file *tfile = file->private_data;
 	struct net_device *dev;
-	int err;
+	int err, i;
 
 	if (tfile->detached)
 		return -EINVAL;
@@ -2833,8 +2918,12 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
 	/* Make sure persistent devices do not get stuck in
 	 * xoff state.
 	 */
-	if (netif_running(tun->dev))
-		netif_tx_wake_all_queues(tun->dev);
+	if (netif_running(tun->dev)) {
+		for (i = 0; i < tun->numqueues; i++) {
+			tfile = rtnl_dereference(tun->tfiles[i]);
+			tun_force_wake_queue(tun, tfile);
+		}
+	}
 
 	strscpy(ifr->ifr_name, tun->dev->name);
 	return 0;
@@ -3630,6 +3719,13 @@ static int tun_queue_resize(struct tun_struct *tun)
 					  dev->tx_queue_len, GFP_KERNEL,
 					  tun_ptr_free);
 
+	if (!ret) {
+		for (i = 0; i < tun->numqueues; i++) {
+			tfile = rtnl_dereference(tun->tfiles[i]);
+			tun_force_wake_queue(tun, tfile);
+		}
+	}
+
 	kfree(rings);
 	return ret;
 }
@@ -3738,6 +3834,29 @@ struct ptr_ring *tun_get_tx_ring(struct file *file)
 }
 EXPORT_SYMBOL_GPL(tun_get_tx_ring);
 
+/* Callers must hold ring.consumer_lock */
+void tun_wake_queue(struct file *file, int consumed)
+{
+	struct tun_file *tfile;
+	struct tun_struct *tun;
+
+	if (file->f_op != &tun_fops)
+		return;
+
+	tfile = file->private_data;
+	if (!tfile)
+		return;
+
+	rcu_read_lock();
+
+	tun = rcu_dereference(tfile->tun);
+	if (tun)
+		__tun_wake_queue(tun, tfile, consumed);
+
+	rcu_read_unlock();
+}
+EXPORT_SYMBOL_GPL(tun_wake_queue);
+
 module_init(tun_init);
 module_exit(tun_cleanup);
 MODULE_DESCRIPTION(DRV_DESCRIPTION);
diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
index 6949b704166d5..3e72b9c6af0ca 100644
--- a/drivers/vhost/net.c
+++ b/drivers/vhost/net.c
@@ -176,13 +176,21 @@ static void *vhost_net_buf_consume(struct vhost_net_buf *rxq)
 	return ret;
 }
 
-static int vhost_net_buf_produce(struct vhost_net_virtqueue *nvq)
+static int vhost_net_buf_produce(struct sock *sk,
+				 struct vhost_net_virtqueue *nvq)
 {
+	struct file *file = sk->sk_socket->file;
 	struct vhost_net_buf *rxq = &nvq->rxq;
 
 	rxq->head = 0;
-	rxq->tail = ptr_ring_consume_batched(nvq->rx_ring, rxq->queue,
-					      VHOST_NET_BATCH);
+	spin_lock(&nvq->rx_ring->consumer_lock);
+	rxq->tail = __ptr_ring_consume_batched(nvq->rx_ring, rxq->queue,
+					       VHOST_NET_BATCH);
+
+	if (rxq->tail)
+		tun_wake_queue(file, rxq->tail);
+
+	spin_unlock(&nvq->rx_ring->consumer_lock);
 	return rxq->tail;
 }
 
@@ -209,14 +217,15 @@ static int vhost_net_buf_peek_len(void *ptr)
 	return __skb_array_len_with_tag(ptr);
 }
 
-static int vhost_net_buf_peek(struct vhost_net_virtqueue *nvq)
+static int vhost_net_buf_peek(struct sock *sk,
+			      struct vhost_net_virtqueue *nvq)
 {
 	struct vhost_net_buf *rxq = &nvq->rxq;
 
 	if (!vhost_net_buf_is_empty(rxq))
 		goto out;
 
-	if (!vhost_net_buf_produce(nvq))
+	if (!vhost_net_buf_produce(sk, nvq))
 		return 0;
 
 out:
@@ -1004,7 +1013,7 @@ static int peek_head_len(struct vhost_net_virtqueue *rvq, struct sock *sk)
 	unsigned long flags;
 
 	if (rvq->rx_ring)
-		return vhost_net_buf_peek(rvq);
+		return vhost_net_buf_peek(sk, rvq);
 
 	spin_lock_irqsave(&sk->sk_receive_queue.lock, flags);
 	head = skb_peek(&sk->sk_receive_queue);
diff --git a/include/linux/if_tun.h b/include/linux/if_tun.h
index 80166eb62f41c..5f3e206c7a737 100644
--- a/include/linux/if_tun.h
+++ b/include/linux/if_tun.h
@@ -22,6 +22,7 @@ struct tun_msg_ctl {
 #if defined(CONFIG_TUN) || defined(CONFIG_TUN_MODULE)
 struct socket *tun_get_socket(struct file *);
 struct ptr_ring *tun_get_tx_ring(struct file *file);
+void tun_wake_queue(struct file *file, int consumed);
 
 static inline bool tun_is_xdp_frame(void *ptr)
 {
@@ -55,6 +56,8 @@ static inline struct ptr_ring *tun_get_tx_ring(struct file *f)
 	return ERR_PTR(-EINVAL);
 }
 
+static inline void tun_wake_queue(struct file *f, int consumed) {}
+
 static inline bool tun_is_xdp_frame(void *ptr)
 {
 	return false;
diff --git a/include/linux/ptr_ring.h b/include/linux/ptr_ring.h
index d2c3629bbe451..c95e891903f05 100644
--- a/include/linux/ptr_ring.h
+++ b/include/linux/ptr_ring.h
@@ -96,6 +96,20 @@ static inline bool ptr_ring_full_bh(struct ptr_ring *r)
 	return ret;
 }
 
+/* Note: callers invoking this in a loop must use a compiler barrier,
+ * for example cpu_relax(). Callers must hold producer_lock.
+ */
+static inline int __ptr_ring_check_produce(struct ptr_ring *r)
+{
+	if (unlikely(!r->size))
+		return -EINVAL;
+
+	if (data_race(r->queue[r->producer]))
+		return -ENOSPC;
+
+	return 0;
+}
+
 /* Note: callers invoking this in a loop must use a compiler barrier,
  * for example cpu_relax(). Callers must hold producer_lock.
  * Callers are responsible for making sure pointer that is being queued
@@ -103,8 +117,10 @@ static inline bool ptr_ring_full_bh(struct ptr_ring *r)
  */
 static inline int __ptr_ring_produce(struct ptr_ring *r, void *ptr)
 {
-	if (unlikely(!r->size) || data_race(r->queue[r->producer]))
-		return -ENOSPC;
+	int p = __ptr_ring_check_produce(r);
+
+	if (p)
+		return p;
 
 	/* Make sure the pointer we are storing points to a valid data. */
 	/* Pairs with the dependency ordering in __ptr_ring_consume. */
diff --git a/include/uapi/linux/if_tun.h b/include/uapi/linux/if_tun.h
index 79d53c7a1ebdc..a0ddc50a75342 100644
--- a/include/uapi/linux/if_tun.h
+++ b/include/uapi/linux/if_tun.h
@@ -69,6 +69,10 @@
 #define IFF_NAPI_FRAGS	0x0020
 /* Used in TUNSETIFF to bring up tun/tap without carrier */
 #define IFF_NO_CARRIER	0x0040
+/* Stop the queue instead of dropping when the internal ring is full, so an
+ * attached qdisc applies backpressure instead of being bypassed.
+ */
+#define IFF_BACKPRESSURE	0x0080
 #define IFF_NO_PI	0x1000
 /* This flag has no real effect */
 #define IFF_ONE_QUEUE	0x2000
diff --git a/tools/include/uapi/linux/if_tun.h b/tools/include/uapi/linux/if_tun.h
index 2ec07de1d73be..2c85525704c16 100644
--- a/tools/include/uapi/linux/if_tun.h
+++ b/tools/include/uapi/linux/if_tun.h
@@ -67,6 +67,10 @@
 #define IFF_TAP		0x0002
 #define IFF_NAPI	0x0010
 #define IFF_NAPI_FRAGS	0x0020
+/* Stop the queue instead of dropping when the internal ring is full, so an
+ * attached qdisc applies backpressure instead of being bypassed.
+ */
+#define IFF_BACKPRESSURE	0x0080
 #define IFF_NO_PI	0x1000
 /* This flag has no real effect */
 #define IFF_ONE_QUEUE	0x2000

3/2 2026/08/01 07:55 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 7460
							output: 28
							thoughts: 421
						

Thoughts:
**Analyzing a Patch for TUN/TAP and vhost_net Backpressure**

Okay, so I've got a new patch here that's tweaking the TUN/TAP and vhost_net drivers. It's introducing a new `IFF_BACKPRESSURE` flag specifically for TUN/TAP devices. The key thing is that, instead of the usual packet dropping when the internal ring buffer is full, it'll stop the queue and allow the attached qdisc to manage the backpressure. That's a pretty interesting change to how these drivers behave under load.

Looks like the changes touch a fair number of files: `drivers/net/tun.c`, `drivers/vhost/net.c`, some header files in the include directories, and even the UAPI definitions. I can confirm this is fully functional and exposed through the TUNSETIFF ioctl on `/dev/net/tun` from user space, which is good for accessibility. They've also modified the vhost_net driver to handle queue waking when consuming packets from the ring, which makes sense for the overall flow.

Now, the question is, is this something we should consider fuzzing? Given that it modifies core TUN/TAP logic and those are highly reachable targets, *especially* given how heavily they're fuzzed, I'd say this is definitely fuzzable. The new `IFF_BACKPRESSURE` flag is added to `TUN_FEATURES`, so it looks like it's been properly integrated. I see the functions being modified as `tun_net_xmit`, `tun_ring_recv`, `tun_set_iff`, `tun_queue_resize`, `vhost_net_buf_produce`, and `vhost_net_buf_peek` which is a substantial impact on the core logic and critical areas for testing. I also see new functions like `tun_force_wake_queue`, `__tun_wake_queue`, `tun_ring_consume`, and `tun_wake_queue` which is a good indication of the internal mechanics being changed.

Time to look into the necessary configurations for this to work. Obviously, TUN/TAP itself needs `CONFIG_TUN`, and vhost_net, requires `CONFIG_VHOST_NET`. Let's just confirm those requirements exist in `drivers/net/tun.c` and `drivers/vhost/net.c`, so I should be good to go.

Alright, I'll use the default grepper to verify configs.



4/2 2026/08/01 07:56 tool grepper
0m Args:
{
  "Expression": "config TUN",
  "PathPrefix": "drivers/net/Kconfig"
}

Results:
{
  "Output": "drivers/net/Kconfig=386=config RIONET_RX_SIZE\n--\ndrivers/net/Kconfig-390-\ndrivers/net/Kconfig:391:config TUN\ndrivers/net/Kconfig-392-\ttristate \"Universal TUN/TAP device driver support\"\n--\ndrivers/net/Kconfig=415=config TAP\n--\ndrivers/net/Kconfig-420-\ndrivers/net/Kconfig:421:config TUN_VNET_CROSS_LE\ndrivers/net/Kconfig-422-\tbool \"Support for cross-endian vnet headers on little-endian kernels\"\n"
}

5/2 2026/08/01 07:56 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 8598
							output: 32
							thoughts: 9
						

Thoughts:
Okay, here's my interpretation of that thought process, tailored for an expert audience, and written in the first person:

**Initial Assessment: VHOST_NET Inquiry**

Alright, the first thought that pops into my head is to check into `VHOST_NET`. It's the most likely starting point when troubleshooting something like this. I need to quickly determine the state of that subsystem, it usually has some tell tale logs and issues if not configured correctly. I'll need to confirm its presence, configuration, and status of any associated networking components. I should probably start looking for any obvious error messages or performance bottlenecks related to it. Let's dig in.



6/2 2026/08/01 07:56 tool grepper
0m Args:
{
  "Expression": "config VHOST_NET",
  "PathPrefix": "drivers/vhost/Kconfig"
}

Results:
{
  "Output": "drivers/vhost/Kconfig=32=if VHOST_MENU\ndrivers/vhost/Kconfig-33-\ndrivers/vhost/Kconfig:34:config VHOST_NET\ndrivers/vhost/Kconfig-35-\ttristate \"Host kernel accelerator for virtio net\"\n"
}

7/2 2026/08/01 07:56 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 8861
							output: 29
							thoughts: 13
						

Thoughts:
Okay, here's my summary, taking the perspective of someone knowledgeable in the field:

**Dependency Deep Dive: VHOST_NET**

Alright, let's get down to brass tacks. I need to understand this VHOST_NET module, inside and out. The immediate question burning in my mind is: what are its dependencies? I can't just dive in without knowing the foundation it's built on. I have to trace everything and understand the whole picture. I need to identify any other kernel modules or system components this depends on. This is crucial for troubleshooting, optimizing, and even just for architecting my approach to whatever I'm working on. Dependency discovery is the first step toward getting the lay of the land, understanding potential conflicts, and ensuring proper configuration. This is non-negotiable.



8/2 2026/08/01 07:56 tool grepper
0m Args:
{
  "Expression": "depends on",
  "PathPrefix": "drivers/vhost/Kconfig"
}

Results:
{
  "Output": "drivers/vhost/Kconfig=34=config VHOST_NET\ndrivers/vhost/Kconfig-35-\ttristate \"Host kernel accelerator for virtio net\"\ndrivers/vhost/Kconfig:36:\tdepends on NET \u0026\u0026 EVENTFD \u0026\u0026 (TUN || !TUN) \u0026\u0026 (TAP || !TAP)\ndrivers/vhost/Kconfig-37-\tselect VHOST\n--\ndrivers/vhost/Kconfig=46=config VHOST_SCSI\ndrivers/vhost/Kconfig-47-\ttristate \"VHOST_SCSI TCM fabric driver\"\ndrivers/vhost/Kconfig:48:\tdepends on TARGET_CORE \u0026\u0026 EVENTFD\ndrivers/vhost/Kconfig-49-\tselect VHOST\n--\ndrivers/vhost/Kconfig=56=config VHOST_VSOCK\ndrivers/vhost/Kconfig-57-\ttristate \"vhost virtio-vsock driver\"\ndrivers/vhost/Kconfig:58:\tdepends on VSOCKETS \u0026\u0026 EVENTFD\ndrivers/vhost/Kconfig-59-\tselect VHOST\n--\ndrivers/vhost/Kconfig=70=config VHOST_VDPA\ndrivers/vhost/Kconfig-71-\ttristate \"Vhost driver for vDPA-based backend\"\ndrivers/vhost/Kconfig:72:\tdepends on EVENTFD\ndrivers/vhost/Kconfig-73-\tselect VHOST\ndrivers/vhost/Kconfig-74-\tselect IRQ_BYPASS_MANAGER\ndrivers/vhost/Kconfig:75:\tdepends on VDPA\ndrivers/vhost/Kconfig-76-\thelp\n"
}

9/2 2026/08/01 07:56 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 9474
							output: 33
							thoughts: 352
						

Thoughts:
**Analyzing the Network Driver Patch**

Okay, so I'm looking at this patch and immediately I see `TUN` and `VHOST_NET` as the key configurations involved. Wait, what about `EVENTFD`? It's usually enabled, but just to be thorough, I should include it in my thinking. Now, a quick check… yep, `VHOST_NET` *does* depend on both `NET` and `EVENTFD`. And we already know `NET` is always enabled, so that's good.

Right, let's identify the specific symbols the patch is touching. I see it's modifying:

*   `tun_net_xmit`
*   `tun_ring_recv` (with a change now taking `tun` and `tfile`) - but it is static
*   `tun_set_iff` - which is static, but reachable via `tun_chr_ioctl`.
*   `tun_queue_resize` - this is also static, reachable via `tun_chr_ioctl`.
*   `tun_wake_queue` - aha, this one's an exported symbol!
*   `vhost_net_buf_produce` - which is static
*   `vhost_net_buf_peek` - and this one is also static

Okay, so the most important areas to focus on seem to be:

*   `tun_net_xmit` – always important in network drivers
*   `tun_wake_queue` – critical because it's exported, and therefore has external dependencies.
*   `tun_chr_ioctl` – because it touches both `tun_set_iff` and `tun_queue_resize`
*   And finally, I need to look into `vhost/net.c`, because I suspect there might be a change to the `vhost_net` ioctls and open or release functions. Wait - it looks like `vhost_net_buf_produce` is called by `vhost_net_buf_peek`. It looks like that’s called by `peek_head_len`, which in turn is called by something like `handle_rx` in `vhost/net.c`.

Okay, I need to see exactly where `peek_head_len` is used. Time to dive into `vhost/net.c` and figure out what's going on with this.



10/2 2026/08/01 07:56 tool grepper
0m Args:
{
  "Expression": "peek_head_len",
  "PathPrefix": "drivers/vhost/net.c"
}

Results:
{
  "Output": "drivers/vhost/net.c=983=static void handle_tx(struct vhost_net *net)\n--\ndrivers/vhost/net.c-1008-\ndrivers/vhost/net.c:1009:static int peek_head_len(struct vhost_net_virtqueue *rvq, struct sock *sk)\ndrivers/vhost/net.c-1010-{\n--\ndrivers/vhost/net.c-1029-\ndrivers/vhost/net.c:1030:static int vhost_net_rx_peek_head_len(struct vhost_net *net, struct sock *sk,\ndrivers/vhost/net.c-1031-\t\t\t\t      bool *busyloop_intr, unsigned int *count)\n--\ndrivers/vhost/net.c-1036-\tstruct vhost_virtqueue *tvq = \u0026tnvq-\u003evq;\ndrivers/vhost/net.c:1037:\tint len = peek_head_len(rnvq, sk);\ndrivers/vhost/net.c-1038-\n--\ndrivers/vhost/net.c-1045-\ndrivers/vhost/net.c:1046:\t\tlen = peek_head_len(rnvq, sk);\ndrivers/vhost/net.c-1047-\t}\n--\ndrivers/vhost/net.c=1149=static void handle_rx(struct vhost_net *net)\n--\ndrivers/vhost/net.c-1201-\tdo {\ndrivers/vhost/net.c:1202:\t\tsock_len = vhost_net_rx_peek_head_len(net, sock-\u003esk,\ndrivers/vhost/net.c-1203-\t\t\t\t\t\t      \u0026busyloop_intr, \u0026count);\n"
}

11/2 2026/08/01 07:56 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 10840
							output: 32
							thoughts: 115
						

Thoughts:
Okay, let's break this down.

**Diving into the Vhost RX Process**

Right, so I'm trying to trace the path of incoming packets in this vhost setup. I'm focusing on the receive path, so I need to understand how data from the guest VM gets into the host. My first thought is that `handle_rx` in `vhost/net.c` is the primary entry point. That's a reasonable assumption for the RX side. Now, a slight wrinkle... `handle_rx` is a *static* function. Hmm, that suggests it's likely called from within the same compilation unit, and likely *not* directly exposed to, say, an interrupt handler. It's probably being invoked by some worker thread or similar mechanism. I need to figure out *how* it's getting called.

Okay, let's backtrack a bit. The typical vhost setup involves ioctls for configuration. Could it be triggered by `vhost_net_ioctl` or maybe `vhost_net_chr_write`? No, I'm pretty sure `vhost_net_ioctl` is primarily used for setting up the backend, configuring memory regions, and things like that, not necessarily for direct packet injection. So, I need to see *how* the guest's data is pushed into the host.

Alright, a likely candidate here is the TUN device. Let me check the `tun_chr_ioctl` function in `drivers/net/tun.c`. It's possible the setup involves some sort of ioctl call to send the data into the network stack. That's the logical next step.



12/2 2026/08/01 07:56 tool grepper
0m Args:
{
  "Expression": "tun_chr_ioctl",
  "PathPrefix": "drivers/net/tun.c"
}

Results:
{
  "Output": "drivers/net/tun.c=3101=static unsigned char tun_get_addr_len(unsigned short type)\n--\ndrivers/net/tun.c-3138-\ndrivers/net/tun.c:3139:static long __tun_chr_ioctl(struct file *file, unsigned int cmd,\ndrivers/net/tun.c-3140-\t\t\t    unsigned long arg, int ifreq_len)\n--\ndrivers/net/tun.c-3215-\ndrivers/net/tun.c:3216:\tnetif_info(tun, drv, tun-\u003edev, \"tun_chr_ioctl cmd %u\\n\", cmd);\ndrivers/net/tun.c-3217-\n--\ndrivers/net/tun.c-3432-\ndrivers/net/tun.c:3433:static long tun_chr_ioctl(struct file *file,\ndrivers/net/tun.c-3434-\t\t\t  unsigned int cmd, unsigned long arg)\ndrivers/net/tun.c-3435-{\ndrivers/net/tun.c:3436:\treturn __tun_chr_ioctl(file, cmd, arg, sizeof (struct ifreq));\ndrivers/net/tun.c-3437-}\n--\ndrivers/net/tun.c=3440=static long tun_chr_compat_ioctl(struct file *file,\n--\ndrivers/net/tun.c-3463-\t */\ndrivers/net/tun.c:3464:\treturn __tun_chr_ioctl(file, cmd, arg, sizeof(struct compat_ifreq));\ndrivers/net/tun.c-3465-}\n--\ndrivers/net/tun.c=3562=static const struct file_operations tun_fops = {\n--\ndrivers/net/tun.c-3566-\t.poll\t= tun_chr_poll,\ndrivers/net/tun.c:3567:\t.unlocked_ioctl\t= tun_chr_ioctl,\ndrivers/net/tun.c-3568-#ifdef CONFIG_COMPAT\n"
}

13/2 2026/08/01 07:56 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 11859
							output: 34
							thoughts: 82
						

Thoughts:
Okay, let's break this down.

**Diving into the TUN/VHOST Architecture**

Alright, my focus needs to be laser-sharp here. It looks like `tun_chr_ioctl` is the central IOCTL handler in this whole TUN setup. Knowing that, I need to zoom in on a few crucial functions and understand how they interact. Specifically, I'm thinking about: `tun_net_xmit`, which handles the network transmission; `tun_chr_ioctl`, of course, is a control plane entrypoint. `tun_wake_queue` and finally `vhost_net_ioctl` which is key for understanding how things integrate with vhost.

I'm particularly interested in `vhost_net_ioctl` and I need to check out where that is defined. The obvious place to look would be in the `drivers/vhost/net.c` file. Time to dive into the code.



14/2 2026/08/01 07:56 tool grepper
0m Args:
{
  "Expression": "vhost_net_ioctl",
  "PathPrefix": "drivers/vhost/net.c"
}

Results:
{
  "Output": "drivers/vhost/net.c=1726=static long vhost_net_set_owner(struct vhost_net *n)\n--\ndrivers/vhost/net.c-1746-\ndrivers/vhost/net.c:1747:static long vhost_net_ioctl(struct file *f, unsigned int ioctl,\ndrivers/vhost/net.c-1748-\t\t\t    unsigned long arg)\n--\ndrivers/vhost/net.c=1875=static const struct file_operations vhost_net_fops = {\n--\ndrivers/vhost/net.c-1880-\t.poll           = vhost_net_chr_poll,\ndrivers/vhost/net.c:1881:\t.unlocked_ioctl = vhost_net_ioctl,\ndrivers/vhost/net.c-1882-\t.compat_ioctl   = compat_ptr_ioctl,\n"
}

15/2 2026/08/01 07:56 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 12411
							output: 34
							thoughts: 125
						

Thoughts:
**My Analysis of the TUN Device Backpressure Implementation**

Okay, so this patch introduces a new `IFF_BACKPRESSURE` flag, which is enabled using the `TUNSETIFF` ioctl. The critical thing here is that when this flag is active, the `tun_net_xmit` function will now actively halt the transmission queue if the ring buffer fills up. This is the core of the backpressure mechanism.

Now, the interesting part is how this halted queue gets restarted. The logic hinges on two key functions. First, `vhost_net`, when it consumes packets from the TUN device, is going to call `tun_wake_queue`.  Second, `tun_do_read`, which also consumes packets, is also responsible for calling `tun_wake_queue`.  I know `tun_do_read` is called from `tun_chr_read_iter`, so this is where I need to focus to understand how data is actually pulled from the device. Let me drill down into `tun_chr_read_iter` and its call to `tun_do_read` and see how this all connects.



16/2 2026/08/01 07:56 tool grepper
0m Args:
{
  "Expression": "tun_chr_read_iter",
  "PathPrefix": "drivers/net/tun.c"
}

Results:
{
  "Output": "drivers/net/tun.c=2245=static ssize_t tun_do_read(struct tun_struct *tun, struct tun_file *tfile,\n--\ndrivers/net/tun.c-2281-\ndrivers/net/tun.c:2282:static ssize_t tun_chr_read_iter(struct kiocb *iocb, struct iov_iter *to)\ndrivers/net/tun.c-2283-{\n--\ndrivers/net/tun.c=3562=static const struct file_operations tun_fops = {\ndrivers/net/tun.c-3563-\t.owner\t= THIS_MODULE,\ndrivers/net/tun.c:3564:\t.read_iter  = tun_chr_read_iter,\ndrivers/net/tun.c-3565-\t.write_iter = tun_chr_write_iter,\n"
}

17/2 2026/08/01 07:56 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 13039
							output: 32
							thoughts: 430
						

Thoughts:
**Analyzing TUN/VHOST Hot Paths for Symbolic Focus**

Okay, so I'm trying to figure out the best symbols to focus on for this analysis of the TUN/VHOST code. `tun_chr_read_iter` is the read handler, so it's definitely on my list. The instructions suggest I avoid generic hot-path functions to get a more focused analysis.

The list I had initially was: `tun_net_xmit`, `tun_chr_ioctl`, `tun_chr_read_iter`, `tun_wake_queue`, and `vhost_net_ioctl`.

Hold on, `tun_net_xmit` is *definitely* a hot path function. It’s essentially the `ndo_start_xmit` for TUN devices. I need to avoid those, right? And `tun_chr_read_iter` is also a hot path because, well, it's the read handler. D'oh!

Now, `tun_wake_queue` is called every time a packet is consumed if the queue was stopped. It *is* exported, which is good. But... is it a hot path? It's called when consuming packets. I need to figure that out. Hang on, wait, `tun_wake_queue` is only called when `rxq->tail` is non-zero in `vhost_net_buf_produce`. That makes a difference. Is *that* a hot path? More investigation is required.

Let's look at `tun_set_iff` then. It's static, which is good, but is it a hot path? No, not really. It's called from `__tun_chr_ioctl`, which is an ioctl handler. Is `__tun_chr_ioctl` a hot path? No. What about `tun_queue_resize`? That's called from `__tun_chr_ioctl` when `TUNSETQUEUE` is called. That doesn't seem to be a hot path either. Okay, let's keep going. `vhost_net_ioctl` isn't a hot path either.

Now, I should check whether `tun_set_iff` is inlined. It's quite large, so it's probably *not* inlined. I should double-check that size to be sure, though. Right, I need to get some more data on that.



18/2 2026/08/01 07:56 tool grepper
0m Args:
{
  "Expression": "tun_set_iff",
  "PathPrefix": "drivers/net/tun.c"
}

Results:
{
  "Output": "drivers/net/tun.c=2783=static const struct attribute_group tun_attr_group = {\n--\ndrivers/net/tun.c-2786-\ndrivers/net/tun.c:2787:static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)\ndrivers/net/tun.c-2788-{\n--\ndrivers/net/tun.c=3139=static long __tun_chr_ioctl(struct file *file, unsigned int cmd,\n--\ndrivers/net/tun.c-3186-\ndrivers/net/tun.c:3187:\t\tret = tun_set_iff(net, file, \u0026ifr);\ndrivers/net/tun.c-3188-\n"
}

19/2 2026/08/01 07:56 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 14219
							output: 32
							thoughts: 414
						

Thoughts:
**Analyzing Key Symbols in the Code**

Okay, let's break this down. My goal is to identify the most relevant functions for this particular patch. Right off the bat, `tun_set_iff` jumps out. It's not inlined, and it spans a significant portion of the code (lines 2787 to roughly 3100). That makes it a strong candidate for inclusion in my list of focus symbols. `tun_queue_resize` also looks promising for similar reasons.

Now, `tun_wake_queue`... it's exported, so definitely not inlined. It's core to the functionality introduced by the new feature, so it seems like a good choice despite the instruction to "Avoid listing generic hot-path functions." The caveat being that `tun_wake_queue` is, in fact, specific to this new feature. Given that this is a feature, and not simply an optimization, it seems justifiable to include it.

Initially, I considered `vhost_net_ioctl`, but this patch doesn't actually touch it. It does, however, modify `vhost_net_buf_produce` and `vhost_net_buf_peek`. Hmm, are these hot-path functions? Yes, as they're involved in every packet within `handle_rx`. So, I'll avoid listing those, as suggested.

So far, my list looks like this:

*   `tun_set_iff`
*   `tun_queue_resize`
*   `tun_wake_queue`

Okay, before I finalize, I need to double-check `tun_wake_queue`. It's called from `vhost_net_buf_produce`, which is called from `vhost_net_buf_peek`, which is called from `peek_head_len`, which is ultimately called from `handle_rx` in a loop. Yep, it's definitely a hot-path function. But, wait, I keep coming back to the fact that it's the primary new exported function. It's reasonable to include it.

Finally, I should include something related to the user interface. Let's add either `__tun_chr_ioctl` or `tun_chr_ioctl`.

Now, let me just quickly double-check that `tun_queue_resize` makes sense. Right, all seems good.

**Final List**

Okay, here's my final list of focus symbols:

*   `tun_set_iff`
*   `tun_queue_resize`
*   `tun_wake_queue`
*   `tun_chr_ioctl` (or `__tun_chr_ioctl`)



20/2 2026/08/01 07:56 tool grepper
0m Args:
{
  "Expression": "tun_queue_resize",
  "PathPrefix": "drivers/net/tun.c"
}

Results:
{
  "Output": "drivers/net/tun.c=3685=static const struct ethtool_ops tun_ethtool_ops = {\n--\ndrivers/net/tun.c-3698-\ndrivers/net/tun.c:3699:static int tun_queue_resize(struct tun_struct *tun)\ndrivers/net/tun.c-3700-{\n--\ndrivers/net/tun.c=3733=static int tun_device_event(struct notifier_block *unused,\n--\ndrivers/net/tun.c-3744-\tcase NETDEV_CHANGE_TX_QUEUE_LEN:\ndrivers/net/tun.c:3745:\t\tif (tun_queue_resize(tun))\ndrivers/net/tun.c-3746-\t\t\treturn NOTIFY_BAD;\n"
}

21/2 2026/08/01 07:56 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 15449
							output: 34
							thoughts: 56
						

Thoughts:
Okay, here's my take on those thoughts, tailored for an expert audience:

**Analyzing the `tun_queue_resize` Function**

Alright, so we're dealing with the `NETDEV_CHANGE_TX_QUEUE_LEN` event, which triggers a call to `tun_queue_resize`. The good news is, from what I can tell, this isn't in a performance-critical path – that's something to keep in mind, and always a good starting point. Less pressure on optimization there, though we still want to ensure it’s done correctly.

Now, let's take a look at `tun_force_wake_queue`. It's a new static function, which immediately makes me curious. I'll need to dig into its purpose within the context of the queue length change. Wondering if this is about ensuring that the changes are immediately reflected on the hardware layer. Or if it is some sort of an optimization function.



22/2 2026/08/01 07:56 tool grepper
0m Args:
{
  "Expression": "tun_force_wake_queue",
  "PathPrefix": "drivers/net/tun.c"
}

Results:
{
  "Output": "drivers/net/tun.c=657=static void tun_detach_all(struct net_device *dev)\n--\ndrivers/net/tun.c-700-\ndrivers/net/tun.c:701:static void tun_force_wake_queue(struct tun_struct *tun,\ndrivers/net/tun.c-702-\t\t\t\t struct tun_file *tfile)\n--\ndrivers/net/tun.c=715=static int tun_attach(struct tun_struct *tun, struct file *file,\n--\ndrivers/net/tun.c-759-\ttfile-\u003esocket.sk-\u003esk_shutdown \u0026= ~RCV_SHUTDOWN;\ndrivers/net/tun.c:760:\ttun_force_wake_queue(tun, tfile);\ndrivers/net/tun.c-761-\n--\ndrivers/net/tun.c=2787=static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)\n--\ndrivers/net/tun.c-2923-\t\t\ttfile = rtnl_dereference(tun-\u003etfiles[i]);\ndrivers/net/tun.c:2924:\t\t\ttun_force_wake_queue(tun, tfile);\ndrivers/net/tun.c-2925-\t\t}\n--\ndrivers/net/tun.c=3699=static int tun_queue_resize(struct tun_struct *tun)\n--\ndrivers/net/tun.c-3724-\t\t\ttfile = rtnl_dereference(tun-\u003etfiles[i]);\ndrivers/net/tun.c:3725:\t\t\ttun_force_wake_queue(tun, tfile);\ndrivers/net/tun.c-3726-\t\t}\n"
}

23/2 2026/08/01 07:56 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 16182
							output: 30
							thoughts: 90
						

Thoughts:
Okay, here's my breakdown of this code snippet, expressed as if these were my internal thoughts:

**Analyzing the Callers of `tun_force_wake_queue`**

Right, so `tun_force_wake_queue` is a `static` function. The compiler *might* inline it in each call site, which would make tracing its execution a bit more complicated. But, since it's used in a few different places – `tun_attach`, `tun_set_iff`, and `tun_queue_resize` – inlining isn't guaranteed, and honestly, the compiler might not even optimize it that way. In any case, it's safer and clearer to just list the calling functions directly, so I'll keep track of those: `tun_attach`, `tun_set_iff`, and `tun_queue_resize`.

Now, let's start by digging into `tun_attach`. That's where I'll begin my investigation.



24/2 2026/08/01 07:56 tool grepper
0m Args:
{
  "Expression": "tun_attach",
  "PathPrefix": "drivers/net/tun.c"
}

Results:
{
  "Output": "drivers/net/tun.c=701=static void tun_force_wake_queue(struct tun_struct *tun,\n--\ndrivers/net/tun.c-714-\ndrivers/net/tun.c:715:static int tun_attach(struct tun_struct *tun, struct file *file,\ndrivers/net/tun.c-716-\t\t      bool skip_filter, bool napi, bool napi_frags,\n--\ndrivers/net/tun.c=937=static int tun_net_init(struct net_device *dev)\n--\ndrivers/net/tun.c-965-\tINIT_LIST_HEAD(\u0026tun-\u003edisabled);\ndrivers/net/tun.c:966:\terr = tun_attach(tun, tun-\u003efile, false, ifr-\u003eifr_flags \u0026 IFF_NAPI,\ndrivers/net/tun.c-967-\t\t\t ifr-\u003eifr_flags \u0026 IFF_NAPI_FRAGS, false);\n--\ndrivers/net/tun.c=2787=static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)\n--\ndrivers/net/tun.c-2826-\ndrivers/net/tun.c:2827:\t\terr = tun_attach(tun, file, ifr-\u003eifr_flags \u0026 IFF_NOFILTER,\ndrivers/net/tun.c-2828-\t\t\t\t ifr-\u003eifr_flags \u0026 IFF_NAPI,\n--\ndrivers/net/tun.c=2998=static void tun_detach_filter(struct tun_struct *tun, int n)\n--\ndrivers/net/tun.c-3012-\ndrivers/net/tun.c:3013:static int tun_attach_filter(struct tun_struct *tun)\ndrivers/net/tun.c-3014-{\n--\ndrivers/net/tun.c=3044=static int tun_set_queue(struct file *file, struct ifreq *ifr)\n--\ndrivers/net/tun.c-3060-\t\t\tgoto unlock;\ndrivers/net/tun.c:3061:\t\tret = tun_attach(tun, file, false, tun-\u003eflags \u0026 IFF_NAPI,\ndrivers/net/tun.c-3062-\t\t\t\t tun-\u003eflags \u0026 IFF_NAPI_FRAGS, true);\n--\ndrivers/net/tun.c=3139=static long __tun_chr_ioctl(struct file *file, unsigned int cmd,\n--\ndrivers/net/tun.c-3372-\ndrivers/net/tun.c:3373:\t\tret = tun_attach_filter(tun);\ndrivers/net/tun.c-3374-\t\tbreak;\n"
}

25/2 2026/08/01 07:56 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 17188
							output: 154
							thoughts: 420
						

Thoughts:
**My Assessment of the Patch's Fuzzing Potential**

Okay, so looking at this patch, `tun_attach` seems like another good function to keep an eye on. Let's list the key focus symbols: `tun_set_iff`, `tun_queue_resize`, `tun_attach`, and `tun_wake_queue`. Are there any other potential configurations to consider? The patch alters `drivers/vhost/net.c`, so `CONFIG_VHOST_NET` is relevant. Also, since it's a TUN/TAP modification, `CONFIG_TUN` is definitely involved.

Now, let's just be absolutely certain. If `CONFIG_VHOST_NET` is the only config needed? Let's check the dependency. `CONFIG_VHOST_NET` depends on `NET && EVENTFD && (TUN || !TUN) && (TAP || !TAP)`. So, yes, both `CONFIG_VHOST_NET` and `CONFIG_TUN` are required.

Alright, time to synthesize my conclusions. This patch introduces a new `IFF_BACKPRESSURE` flag for TUN/TAP devices. When enabled, it fundamentally changes how the queues behave in `tun_net_xmit` and `vhost_net` when the internal ring buffer is full – it stops the queue instead of dropping packets, enabling the attached qdisc to apply backpressure. This affects core TUN/TAP logic and the vhost_net driver. Because this change is functional and user-reachable via ioctls and network traffic, it's absolutely ripe for fuzzing.

My final determination is:

WorthFuzzing: true
FocusSymbols: `tun_set_iff`, `tun_queue_resize`, `tun_attach`, `tun_wake_queue`
EnableConfigs: `TUN`, `VHOST_NET`
Reasoning: The patch introduces `IFF_BACKPRESSURE` flag for TUN/TAP devices. When enabled, this modifies the queue handling logic in `tun_net_xmit` and `vhost_net` to stop the queue instead of dropping packets when the ring is full. This is a functional change in core networking and virtualization drivers that is reachable from user space via `TUNSETIFF` ioctl and network traffic, making it highly relevant for fuzzing.



26/2 2026/08/01 07:57 tool set-results
0m Args:
{
  "EnableConfigs": [
    "TUN",
    "VHOST_NET"
  ],
  "FocusSymbols": [
    "tun_set_iff",
    "tun_queue_resize",
    "tun_attach",
    "tun_wake_queue"
  ],
  "Reasoning": "The patch introduces a new IFF_BACKPRESSURE flag for TUN/TAP devices, which modifies the queue handling logic in tun_net_xmit and vhost_net to stop the queue instead of dropping packets when the ring is full. This is a functional change in core networking and virtualization drivers that is reachable from user space via TUNSETIFF ioctl and network traffic, making it highly relevant for fuzzing.",
  "WorthFuzzing": true
}

Results:
{
  "EnableConfigs": [
    "TUN",
    "VHOST_NET"
  ],
  "FocusSymbols": [
    "tun_set_iff",
    "tun_queue_resize",
    "tun_attach",
    "tun_wake_queue"
  ],
  "Reasoning": "The patch introduces a new IFF_BACKPRESSURE flag for TUN/TAP devices, which modifies the queue handling logic in tun_net_xmit and vhost_net to stop the queue instead of dropping packets when the ring is full. This is a functional change in core networking and virtualization drivers that is reachable from user space via TUNSETIFF ioctl and network traffic, making it highly relevant for fuzzing.",
  "WorthFuzzing": true
}

LLM Calls Summary:
Total Calls Total Tokens Avg Tokens Total Duration (Seconds) Avg Duration (Seconds)
Tool Calls Summary:
Total Calls Total Duration (Seconds) Avg Duration (Seconds)