| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * NET3: Garbage Collector For AF_UNIX sockets |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * Garbage Collector: |
|---|
| 5 | 6 | * Copyright (C) Barak A. Pearlmutter. |
|---|
| 6 | | - * Released under the GPL version 2 or later. |
|---|
| 7 | 7 | * |
|---|
| 8 | 8 | * Chopped about by Alan Cox 22/3/96 to make it fit the AF_UNIX socket problem. |
|---|
| 9 | 9 | * If it doesn't work blame me, it worked when Barak sent it. |
|---|
| .. | .. |
|---|
| 23 | 23 | * Future optimizations: |
|---|
| 24 | 24 | * |
|---|
| 25 | 25 | * - don't just push entire root set; process in place |
|---|
| 26 | | - * |
|---|
| 27 | | - * This program is free software; you can redistribute it and/or |
|---|
| 28 | | - * modify it under the terms of the GNU General Public License |
|---|
| 29 | | - * as published by the Free Software Foundation; either version |
|---|
| 30 | | - * 2 of the License, or (at your option) any later version. |
|---|
| 31 | 26 | * |
|---|
| 32 | 27 | * Fixes: |
|---|
| 33 | 28 | * Alan Cox 07 Sept 1997 Vmalloc internal stack as needed. |
|---|
| .. | .. |
|---|
| 209 | 204 | /* The external entry point: unix_gc() */ |
|---|
| 210 | 205 | void unix_gc(void) |
|---|
| 211 | 206 | { |
|---|
| 207 | + struct sk_buff *next_skb, *skb; |
|---|
| 212 | 208 | struct unix_sock *u; |
|---|
| 213 | 209 | struct unix_sock *next; |
|---|
| 214 | 210 | struct sk_buff_head hitlist; |
|---|
| .. | .. |
|---|
| 302 | 298 | |
|---|
| 303 | 299 | spin_unlock(&unix_gc_lock); |
|---|
| 304 | 300 | |
|---|
| 301 | + /* We need io_uring to clean its registered files, ignore all io_uring |
|---|
| 302 | + * originated skbs. It's fine as io_uring doesn't keep references to |
|---|
| 303 | + * other io_uring instances and so killing all other files in the cycle |
|---|
| 304 | + * will put all io_uring references forcing it to go through normal |
|---|
| 305 | + * release.path eventually putting registered files. |
|---|
| 306 | + */ |
|---|
| 307 | + skb_queue_walk_safe(&hitlist, skb, next_skb) { |
|---|
| 308 | + if (skb->scm_io_uring) { |
|---|
| 309 | + __skb_unlink(skb, &hitlist); |
|---|
| 310 | + skb_queue_tail(&skb->sk->sk_receive_queue, skb); |
|---|
| 311 | + } |
|---|
| 312 | + } |
|---|
| 313 | + |
|---|
| 305 | 314 | /* Here we are. Hitlist is filled. Die. */ |
|---|
| 306 | 315 | __skb_queue_purge(&hitlist); |
|---|
| 307 | 316 | |
|---|
| 308 | 317 | spin_lock(&unix_gc_lock); |
|---|
| 309 | 318 | |
|---|
| 319 | + /* There could be io_uring registered files, just push them back to |
|---|
| 320 | + * the inflight list |
|---|
| 321 | + */ |
|---|
| 322 | + list_for_each_entry_safe(u, next, &gc_candidates, link) |
|---|
| 323 | + list_move_tail(&u->link, &gc_inflight_list); |
|---|
| 324 | + |
|---|
| 310 | 325 | /* All candidates should have been detached by now. */ |
|---|
| 311 | 326 | BUG_ON(!list_empty(&gc_candidates)); |
|---|
| 312 | 327 | |
|---|