io_uring/eventfd.c:80:5-24: WARNING: atomic_dec_and_test variation before object free at line 81.

From: kernel test robot
Date: Sun Sep 08 2024 - 08:09:20 EST


tree: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master
head: d1f2d51b711a3b7f1ae1b46701c769c1d580fa7f
commit: 200f3abd14db55f9aadcb74f4e7a678f1c469ba1 io_uring/eventfd: move eventfd handling to separate file
date: 3 months ago
config: hexagon-randconfig-r054-20240908 (https://download.01.org/0day-ci/archive/20240908/202409082039.hnsaIJ3X-lkp@xxxxxxxxx/config)
compiler: clang version 20.0.0git (https://github.com/llvm/llvm-project 05f5a91d00b02f4369f46d076411c700755ae041)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@xxxxxxxxx>
| Closes: https://lore.kernel.org/oe-kbuild-all/202409082039.hnsaIJ3X-lkp@xxxxxxxxx/

cocci warnings: (new ones prefixed by >>)
>> io_uring/eventfd.c:80:5-24: WARNING: atomic_dec_and_test variation before object free at line 81.
io_uring/eventfd.c:154:6-25: WARNING: atomic_dec_and_test variation before object free at line 155.

vim +80 io_uring/eventfd.c

43
44 void io_eventfd_signal(struct io_ring_ctx *ctx)
45 {
46 struct io_ev_fd *ev_fd = NULL;
47
48 if (READ_ONCE(ctx->rings->cq_flags) & IORING_CQ_EVENTFD_DISABLED)
49 return;
50
51 guard(rcu)();
52
53 /*
54 * rcu_dereference ctx->io_ev_fd once and use it for both for checking
55 * and eventfd_signal
56 */
57 ev_fd = rcu_dereference(ctx->io_ev_fd);
58
59 /*
60 * Check again if ev_fd exists incase an io_eventfd_unregister call
61 * completed between the NULL check of ctx->io_ev_fd at the start of
62 * the function and rcu_read_lock.
63 */
64 if (unlikely(!ev_fd))
65 return;
66 if (!atomic_inc_not_zero(&ev_fd->refs))
67 return;
68 if (ev_fd->eventfd_async && !io_wq_current_is_worker())
69 goto out;
70
71 if (likely(eventfd_signal_allowed())) {
72 eventfd_signal_mask(ev_fd->cq_ev_fd, EPOLL_URING_WAKE);
73 } else {
74 if (!atomic_fetch_or(BIT(IO_EVENTFD_OP_SIGNAL_BIT), &ev_fd->ops)) {
75 call_rcu_hurry(&ev_fd->rcu, io_eventfd_do_signal);
76 return;
77 }
78 }
79 out:
> 80 if (atomic_dec_and_test(&ev_fd->refs))
> 81 call_rcu(&ev_fd->rcu, io_eventfd_free);
82 }
83

--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki