Skip to content

Commit cb31821

Browse files
committed
Revert "io_uring: Add support for napi_busy_poll"
This reverts commit adc8682. There's some discussion on the API not being as good as it can be. Rather than ship something and be stuck with it forever, let's revert the NAPI support for now and work on getting something sorted out for the next kernel release instead. Link: https://lore.kernel.org/io-uring/b7bbc124-8502-0ee9-d4c8-7c41b4487264@kernel.dk/ Signed-off-by: Jens Axboe <axboe@kernel.dk>
1 parent d536123 commit cb31821

File tree

1 file changed

+1
-231
lines changed

1 file changed

+1
-231
lines changed

fs/io_uring.c

Lines changed: 1 addition & 231 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,6 @@
6363
#include <net/sock.h>
6464
#include <net/af_unix.h>
6565
#include <net/scm.h>
66-
#include <net/busy_poll.h>
6766
#include <linux/anon_inodes.h>
6867
#include <linux/sched/mm.h>
6968
#include <linux/uaccess.h>
@@ -411,11 +410,6 @@ struct io_ring_ctx {
411410
struct list_head sqd_list;
412411

413412
unsigned long check_cq_overflow;
414-
#ifdef CONFIG_NET_RX_BUSY_POLL
415-
/* used to track busy poll napi_id */
416-
struct list_head napi_list;
417-
spinlock_t napi_lock; /* napi_list lock */
418-
#endif
419413

420414
struct {
421415
unsigned cached_cq_tail;
@@ -1569,10 +1563,6 @@ static __cold struct io_ring_ctx *io_ring_ctx_alloc(struct io_uring_params *p)
15691563
INIT_WQ_LIST(&ctx->locked_free_list);
15701564
INIT_DELAYED_WORK(&ctx->fallback_work, io_fallback_req_func);
15711565
INIT_WQ_LIST(&ctx->submit_state.compl_reqs);
1572-
#ifdef CONFIG_NET_RX_BUSY_POLL
1573-
INIT_LIST_HEAD(&ctx->napi_list);
1574-
spin_lock_init(&ctx->napi_lock);
1575-
#endif
15761566
return ctx;
15771567
err:
15781568
kfree(ctx->dummy_ubuf);
@@ -5730,108 +5720,6 @@ IO_NETOP_FN(send);
57305720
IO_NETOP_FN(recv);
57315721
#endif /* CONFIG_NET */
57325722

5733-
#ifdef CONFIG_NET_RX_BUSY_POLL
5734-
5735-
#define NAPI_TIMEOUT (60 * SEC_CONVERSION)
5736-
5737-
struct napi_entry {
5738-
struct list_head list;
5739-
unsigned int napi_id;
5740-
unsigned long timeout;
5741-
};
5742-
5743-
/*
5744-
* Add busy poll NAPI ID from sk.
5745-
*/
5746-
static void io_add_napi(struct file *file, struct io_ring_ctx *ctx)
5747-
{
5748-
unsigned int napi_id;
5749-
struct socket *sock;
5750-
struct sock *sk;
5751-
struct napi_entry *ne;
5752-
5753-
if (!net_busy_loop_on())
5754-
return;
5755-
5756-
sock = sock_from_file(file);
5757-
if (!sock)
5758-
return;
5759-
5760-
sk = sock->sk;
5761-
if (!sk)
5762-
return;
5763-
5764-
napi_id = READ_ONCE(sk->sk_napi_id);
5765-
5766-
/* Non-NAPI IDs can be rejected */
5767-
if (napi_id < MIN_NAPI_ID)
5768-
return;
5769-
5770-
spin_lock(&ctx->napi_lock);
5771-
list_for_each_entry(ne, &ctx->napi_list, list) {
5772-
if (ne->napi_id == napi_id) {
5773-
ne->timeout = jiffies + NAPI_TIMEOUT;
5774-
goto out;
5775-
}
5776-
}
5777-
5778-
ne = kmalloc(sizeof(*ne), GFP_NOWAIT);
5779-
if (!ne)
5780-
goto out;
5781-
5782-
ne->napi_id = napi_id;
5783-
ne->timeout = jiffies + NAPI_TIMEOUT;
5784-
list_add_tail(&ne->list, &ctx->napi_list);
5785-
out:
5786-
spin_unlock(&ctx->napi_lock);
5787-
}
5788-
5789-
static inline void io_check_napi_entry_timeout(struct napi_entry *ne)
5790-
{
5791-
if (time_after(jiffies, ne->timeout)) {
5792-
list_del(&ne->list);
5793-
kfree(ne);
5794-
}
5795-
}
5796-
5797-
/*
5798-
* Busy poll if globally on and supporting sockets found
5799-
*/
5800-
static bool io_napi_busy_loop(struct list_head *napi_list)
5801-
{
5802-
struct napi_entry *ne, *n;
5803-
5804-
list_for_each_entry_safe(ne, n, napi_list, list) {
5805-
napi_busy_loop(ne->napi_id, NULL, NULL, true,
5806-
BUSY_POLL_BUDGET);
5807-
io_check_napi_entry_timeout(ne);
5808-
}
5809-
return !list_empty(napi_list);
5810-
}
5811-
5812-
static void io_free_napi_list(struct io_ring_ctx *ctx)
5813-
{
5814-
spin_lock(&ctx->napi_lock);
5815-
while (!list_empty(&ctx->napi_list)) {
5816-
struct napi_entry *ne =
5817-
list_first_entry(&ctx->napi_list, struct napi_entry,
5818-
list);
5819-
5820-
list_del(&ne->list);
5821-
kfree(ne);
5822-
}
5823-
spin_unlock(&ctx->napi_lock);
5824-
}
5825-
#else
5826-
static inline void io_add_napi(struct file *file, struct io_ring_ctx *ctx)
5827-
{
5828-
}
5829-
5830-
static inline void io_free_napi_list(struct io_ring_ctx *ctx)
5831-
{
5832-
}
5833-
#endif /* CONFIG_NET_RX_BUSY_POLL */
5834-
58355723
struct io_poll_table {
58365724
struct poll_table_struct pt;
58375725
struct io_kiocb *req;
@@ -5986,7 +5874,6 @@ static int io_poll_check_events(struct io_kiocb *req, bool locked)
59865874
if (unlikely(!filled))
59875875
return -ECANCELED;
59885876
io_cqring_ev_posted(ctx);
5989-
io_add_napi(req->file, ctx);
59905877
} else if (req->result) {
59915878
return 0;
59925879
}
@@ -6237,7 +6124,6 @@ static int __io_arm_poll_handler(struct io_kiocb *req,
62376124
__io_poll_execute(req, mask, poll->events);
62386125
return 0;
62396126
}
6240-
io_add_napi(req->file, req->ctx);
62416127

62426128
/*
62436129
* Release ownership. If someone tried to queue a tw while it was
@@ -8028,13 +7914,7 @@ static int __io_sq_thread(struct io_ring_ctx *ctx, bool cap_entries)
80287914
!(ctx->flags & IORING_SETUP_R_DISABLED))
80297915
ret = io_submit_sqes(ctx, to_submit);
80307916
mutex_unlock(&ctx->uring_lock);
8031-
#ifdef CONFIG_NET_RX_BUSY_POLL
8032-
spin_lock(&ctx->napi_lock);
8033-
if (!list_empty(&ctx->napi_list) &&
8034-
io_napi_busy_loop(&ctx->napi_list))
8035-
++ret;
8036-
spin_unlock(&ctx->napi_lock);
8037-
#endif
7917+
80387918
if (to_submit && wq_has_sleeper(&ctx->sqo_sq_wait))
80397919
wake_up(&ctx->sqo_sq_wait);
80407920
if (creds)
@@ -8172,9 +8052,6 @@ struct io_wait_queue {
81728052
struct io_ring_ctx *ctx;
81738053
unsigned cq_tail;
81748054
unsigned nr_timeouts;
8175-
#ifdef CONFIG_NET_RX_BUSY_POLL
8176-
unsigned busy_poll_to;
8177-
#endif
81788055
};
81798056

81808057
static inline bool io_should_wake(struct io_wait_queue *iowq)
@@ -8236,87 +8113,6 @@ static inline int io_cqring_wait_schedule(struct io_ring_ctx *ctx,
82368113
return 1;
82378114
}
82388115

8239-
#ifdef CONFIG_NET_RX_BUSY_POLL
8240-
static void io_adjust_busy_loop_timeout(struct timespec64 *ts,
8241-
struct io_wait_queue *iowq)
8242-
{
8243-
unsigned busy_poll_to = READ_ONCE(sysctl_net_busy_poll);
8244-
struct timespec64 pollto = ns_to_timespec64(1000 * (s64)busy_poll_to);
8245-
8246-
if (timespec64_compare(ts, &pollto) > 0) {
8247-
*ts = timespec64_sub(*ts, pollto);
8248-
iowq->busy_poll_to = busy_poll_to;
8249-
} else {
8250-
u64 to = timespec64_to_ns(ts);
8251-
8252-
do_div(to, 1000);
8253-
iowq->busy_poll_to = to;
8254-
ts->tv_sec = 0;
8255-
ts->tv_nsec = 0;
8256-
}
8257-
}
8258-
8259-
static inline bool io_busy_loop_timeout(unsigned long start_time,
8260-
unsigned long bp_usec)
8261-
{
8262-
if (bp_usec) {
8263-
unsigned long end_time = start_time + bp_usec;
8264-
unsigned long now = busy_loop_current_time();
8265-
8266-
return time_after(now, end_time);
8267-
}
8268-
return true;
8269-
}
8270-
8271-
static bool io_busy_loop_end(void *p, unsigned long start_time)
8272-
{
8273-
struct io_wait_queue *iowq = p;
8274-
8275-
return signal_pending(current) ||
8276-
io_should_wake(iowq) ||
8277-
io_busy_loop_timeout(start_time, iowq->busy_poll_to);
8278-
}
8279-
8280-
static void io_blocking_napi_busy_loop(struct list_head *napi_list,
8281-
struct io_wait_queue *iowq)
8282-
{
8283-
unsigned long start_time =
8284-
list_is_singular(napi_list) ? 0 :
8285-
busy_loop_current_time();
8286-
8287-
do {
8288-
if (list_is_singular(napi_list)) {
8289-
struct napi_entry *ne =
8290-
list_first_entry(napi_list,
8291-
struct napi_entry, list);
8292-
8293-
napi_busy_loop(ne->napi_id, io_busy_loop_end, iowq,
8294-
true, BUSY_POLL_BUDGET);
8295-
io_check_napi_entry_timeout(ne);
8296-
break;
8297-
}
8298-
} while (io_napi_busy_loop(napi_list) &&
8299-
!io_busy_loop_end(iowq, start_time));
8300-
}
8301-
8302-
static void io_putback_napi_list(struct io_ring_ctx *ctx,
8303-
struct list_head *napi_list)
8304-
{
8305-
struct napi_entry *cne, *lne;
8306-
8307-
spin_lock(&ctx->napi_lock);
8308-
list_for_each_entry(cne, &ctx->napi_list, list)
8309-
list_for_each_entry(lne, napi_list, list)
8310-
if (cne->napi_id == lne->napi_id) {
8311-
list_del(&lne->list);
8312-
kfree(lne);
8313-
break;
8314-
}
8315-
list_splice(napi_list, &ctx->napi_list);
8316-
spin_unlock(&ctx->napi_lock);
8317-
}
8318-
#endif /* CONFIG_NET_RX_BUSY_POLL */
8319-
83208116
/*
83218117
* Wait until events become available, if we don't already have some. The
83228118
* application must reap them itself, as they reside on the shared cq ring.
@@ -8329,9 +8125,6 @@ static int io_cqring_wait(struct io_ring_ctx *ctx, int min_events,
83298125
struct io_rings *rings = ctx->rings;
83308126
ktime_t timeout = KTIME_MAX;
83318127
int ret;
8332-
#ifdef CONFIG_NET_RX_BUSY_POLL
8333-
LIST_HEAD(local_napi_list);
8334-
#endif
83358128

83368129
do {
83378130
io_cqring_overflow_flush(ctx);
@@ -8354,29 +8147,13 @@ static int io_cqring_wait(struct io_ring_ctx *ctx, int min_events,
83548147
return ret;
83558148
}
83568149

8357-
#ifdef CONFIG_NET_RX_BUSY_POLL
8358-
iowq.busy_poll_to = 0;
8359-
if (!(ctx->flags & IORING_SETUP_SQPOLL)) {
8360-
spin_lock(&ctx->napi_lock);
8361-
list_splice_init(&ctx->napi_list, &local_napi_list);
8362-
spin_unlock(&ctx->napi_lock);
8363-
}
8364-
#endif
83658150
if (uts) {
83668151
struct timespec64 ts;
83678152

83688153
if (get_timespec64(&ts, uts))
83698154
return -EFAULT;
8370-
#ifdef CONFIG_NET_RX_BUSY_POLL
8371-
if (!list_empty(&local_napi_list))
8372-
io_adjust_busy_loop_timeout(&ts, &iowq);
8373-
#endif
83748155
timeout = ktime_add_ns(timespec64_to_ktime(ts), ktime_get_ns());
83758156
}
8376-
#ifdef CONFIG_NET_RX_BUSY_POLL
8377-
else if (!list_empty(&local_napi_list))
8378-
iowq.busy_poll_to = READ_ONCE(sysctl_net_busy_poll);
8379-
#endif
83808157

83818158
init_waitqueue_func_entry(&iowq.wq, io_wake_function);
83828159
iowq.wq.private = current;
@@ -8386,12 +8163,6 @@ static int io_cqring_wait(struct io_ring_ctx *ctx, int min_events,
83868163
iowq.cq_tail = READ_ONCE(ctx->rings->cq.head) + min_events;
83878164

83888165
trace_io_uring_cqring_wait(ctx, min_events);
8389-
#ifdef CONFIG_NET_RX_BUSY_POLL
8390-
if (iowq.busy_poll_to)
8391-
io_blocking_napi_busy_loop(&local_napi_list, &iowq);
8392-
if (!list_empty(&local_napi_list))
8393-
io_putback_napi_list(ctx, &local_napi_list);
8394-
#endif
83958166
do {
83968167
/* if we can't even flush overflow, don't wait for more */
83978168
if (!io_cqring_overflow_flush(ctx)) {
@@ -10176,7 +9947,6 @@ static __cold void io_ring_ctx_free(struct io_ring_ctx *ctx)
101769947
io_req_caches_free(ctx);
101779948
if (ctx->hash_map)
101789949
io_wq_put_hash(ctx->hash_map);
10179-
io_free_napi_list(ctx);
101809950
kfree(ctx->cancel_hash);
101819951
kfree(ctx->dummy_ubuf);
101829952
kfree(ctx->io_buffers);

0 commit comments

Comments
 (0)