*     @csum_level: indicates the number of consecutive checksums found in
  *             the packet minus one that have been verified as
  *             CHECKSUM_UNNECESSARY (max 3)
+ *     @scm_io_uring: SKB holds io_uring registered files
  *     @dst_pending_confirm: need to confirm neighbour
  *     @decrypted: Decrypted SKB
  *     @slow_gro: state present at GRO time, slower prepare step required
 #endif
        __u8                    slow_gro:1;
        __u8                    csum_not_inet:1;
+       __u8                    scm_io_uring:1;
 
 #ifdef CONFIG_NET_SCHED
        __u16                   tc_index;       /* traffic control index */
 
 /* The external entry point: unix_gc() */
 void unix_gc(void)
 {
+       struct sk_buff *next_skb, *skb;
        struct unix_sock *u;
        struct unix_sock *next;
        struct sk_buff_head hitlist;
 
        spin_unlock(&unix_gc_lock);
 
+       /* We need io_uring to clean its registered files, ignore all io_uring
+        * originated skbs. It's fine as io_uring doesn't keep references to
+        * other io_uring instances and so killing all other files in the cycle
+        * will put all io_uring references forcing it to go through normal
+        * release.path eventually putting registered files.
+        */
+       skb_queue_walk_safe(&hitlist, skb, next_skb) {
+               if (skb->scm_io_uring) {
+                       __skb_unlink(skb, &hitlist);
+                       skb_queue_tail(&skb->sk->sk_receive_queue, skb);
+               }
+       }
+
        /* Here we are. Hitlist is filled. Die. */
        __skb_queue_purge(&hitlist);
 
        spin_lock(&unix_gc_lock);
 
+       /* There could be io_uring registered files, just push them back to
+        * the inflight list
+        */
+       list_for_each_entry_safe(u, next, &gc_candidates, link)
+               list_move_tail(&u->link, &gc_inflight_list);
+
        /* All candidates should have been detached by now. */
        BUG_ON(!list_empty(&gc_candidates));