@@ -275,7 +275,8 @@ struct io_ring_ctx {
275
275
* manipulate the list, hence no extra locking is needed there.
276
276
*/
277
277
struct list_head poll_list ;
278
- struct rb_root cancel_tree ;
278
+ struct hlist_head * cancel_hash ;
279
+ unsigned cancel_hash_bits ;
279
280
280
281
spinlock_t inflight_lock ;
281
282
struct list_head inflight_list ;
@@ -355,7 +356,7 @@ struct io_kiocb {
355
356
struct io_ring_ctx * ctx ;
356
357
union {
357
358
struct list_head list ;
358
- struct rb_node rb_node ;
359
+ struct hlist_node hash_node ;
359
360
};
360
361
struct list_head link_list ;
361
362
unsigned int flags ;
@@ -444,6 +445,7 @@ static void io_ring_ctx_ref_free(struct percpu_ref *ref)
444
445
static struct io_ring_ctx * io_ring_ctx_alloc (struct io_uring_params * p )
445
446
{
446
447
struct io_ring_ctx * ctx ;
448
+ int hash_bits ;
447
449
448
450
ctx = kzalloc (sizeof (* ctx ), GFP_KERNEL );
449
451
if (!ctx )
@@ -457,6 +459,21 @@ static struct io_ring_ctx *io_ring_ctx_alloc(struct io_uring_params *p)
457
459
if (!ctx -> completions )
458
460
goto err ;
459
461
462
+ /*
463
+ * Use 5 bits less than the max cq entries, that should give us around
464
+ * 32 entries per hash list if totally full and uniformly spread.
465
+ */
466
+ hash_bits = ilog2 (p -> cq_entries );
467
+ hash_bits -= 5 ;
468
+ if (hash_bits <= 0 )
469
+ hash_bits = 1 ;
470
+ ctx -> cancel_hash_bits = hash_bits ;
471
+ ctx -> cancel_hash = kmalloc ((1U << hash_bits ) * sizeof (struct hlist_head ),
472
+ GFP_KERNEL );
473
+ if (!ctx -> cancel_hash )
474
+ goto err ;
475
+ __hash_init (ctx -> cancel_hash , 1U << hash_bits );
476
+
460
477
if (percpu_ref_init (& ctx -> refs , io_ring_ctx_ref_free ,
461
478
PERCPU_REF_ALLOW_REINIT , GFP_KERNEL ))
462
479
goto err ;
@@ -470,7 +487,6 @@ static struct io_ring_ctx *io_ring_ctx_alloc(struct io_uring_params *p)
470
487
init_waitqueue_head (& ctx -> wait );
471
488
spin_lock_init (& ctx -> completion_lock );
472
489
INIT_LIST_HEAD (& ctx -> poll_list );
473
- ctx -> cancel_tree = RB_ROOT ;
474
490
INIT_LIST_HEAD (& ctx -> defer_list );
475
491
INIT_LIST_HEAD (& ctx -> timeout_list );
476
492
init_waitqueue_head (& ctx -> inflight_wait );
@@ -481,6 +497,7 @@ static struct io_ring_ctx *io_ring_ctx_alloc(struct io_uring_params *p)
481
497
if (ctx -> fallback_req )
482
498
kmem_cache_free (req_cachep , ctx -> fallback_req );
483
499
kfree (ctx -> completions );
500
+ kfree (ctx -> cancel_hash );
484
501
kfree (ctx );
485
502
return NULL ;
486
503
}
@@ -2260,14 +2277,6 @@ static int io_connect(struct io_kiocb *req, const struct io_uring_sqe *sqe,
2260
2277
#endif
2261
2278
}
2262
2279
2263
- static inline void io_poll_remove_req (struct io_kiocb * req )
2264
- {
2265
- if (!RB_EMPTY_NODE (& req -> rb_node )) {
2266
- rb_erase (& req -> rb_node , & req -> ctx -> cancel_tree );
2267
- RB_CLEAR_NODE (& req -> rb_node );
2268
- }
2269
- }
2270
-
2271
2280
static void io_poll_remove_one (struct io_kiocb * req )
2272
2281
{
2273
2282
struct io_poll_iocb * poll = & req -> poll ;
@@ -2279,36 +2288,34 @@ static void io_poll_remove_one(struct io_kiocb *req)
2279
2288
io_queue_async_work (req );
2280
2289
}
2281
2290
spin_unlock (& poll -> head -> lock );
2282
- io_poll_remove_req ( req );
2291
+ hash_del ( & req -> hash_node );
2283
2292
}
2284
2293
2285
2294
static void io_poll_remove_all (struct io_ring_ctx * ctx )
2286
2295
{
2287
- struct rb_node * node ;
2296
+ struct hlist_node * tmp ;
2288
2297
struct io_kiocb * req ;
2298
+ int i ;
2289
2299
2290
2300
spin_lock_irq (& ctx -> completion_lock );
2291
- while ((node = rb_first (& ctx -> cancel_tree )) != NULL ) {
2292
- req = rb_entry (node , struct io_kiocb , rb_node );
2293
- io_poll_remove_one (req );
2301
+ for (i = 0 ; i < (1U << ctx -> cancel_hash_bits ); i ++ ) {
2302
+ struct hlist_head * list ;
2303
+
2304
+ list = & ctx -> cancel_hash [i ];
2305
+ hlist_for_each_entry_safe (req , tmp , list , hash_node )
2306
+ io_poll_remove_one (req );
2294
2307
}
2295
2308
spin_unlock_irq (& ctx -> completion_lock );
2296
2309
}
2297
2310
2298
2311
static int io_poll_cancel (struct io_ring_ctx * ctx , __u64 sqe_addr )
2299
2312
{
2300
- struct rb_node * p , * parent = NULL ;
2313
+ struct hlist_head * list ;
2301
2314
struct io_kiocb * req ;
2302
2315
2303
- p = ctx -> cancel_tree .rb_node ;
2304
- while (p ) {
2305
- parent = p ;
2306
- req = rb_entry (parent , struct io_kiocb , rb_node );
2307
- if (sqe_addr < req -> user_data ) {
2308
- p = p -> rb_left ;
2309
- } else if (sqe_addr > req -> user_data ) {
2310
- p = p -> rb_right ;
2311
- } else {
2316
+ list = & ctx -> cancel_hash [hash_long (sqe_addr , ctx -> cancel_hash_bits )];
2317
+ hlist_for_each_entry (req , list , hash_node ) {
2318
+ if (sqe_addr == req -> user_data ) {
2312
2319
io_poll_remove_one (req );
2313
2320
return 0 ;
2314
2321
}
@@ -2390,7 +2397,7 @@ static void io_poll_complete_work(struct io_wq_work **workptr)
2390
2397
spin_unlock_irq (& ctx -> completion_lock );
2391
2398
return ;
2392
2399
}
2393
- io_poll_remove_req ( req );
2400
+ hash_del ( & req -> hash_node );
2394
2401
io_poll_complete (req , mask , ret );
2395
2402
spin_unlock_irq (& ctx -> completion_lock );
2396
2403
@@ -2425,7 +2432,7 @@ static int io_poll_wake(struct wait_queue_entry *wait, unsigned mode, int sync,
2425
2432
* for finalizing the request, mark us as having grabbed that already.
2426
2433
*/
2427
2434
if (mask && spin_trylock_irqsave (& ctx -> completion_lock , flags )) {
2428
- io_poll_remove_req ( req );
2435
+ hash_del ( & req -> hash_node );
2429
2436
io_poll_complete (req , mask , 0 );
2430
2437
req -> flags |= REQ_F_COMP_LOCKED ;
2431
2438
io_put_req (req );
@@ -2463,20 +2470,10 @@ static void io_poll_queue_proc(struct file *file, struct wait_queue_head *head,
2463
2470
static void io_poll_req_insert (struct io_kiocb * req )
2464
2471
{
2465
2472
struct io_ring_ctx * ctx = req -> ctx ;
2466
- struct rb_node * * p = & ctx -> cancel_tree .rb_node ;
2467
- struct rb_node * parent = NULL ;
2468
- struct io_kiocb * tmp ;
2469
-
2470
- while (* p ) {
2471
- parent = * p ;
2472
- tmp = rb_entry (parent , struct io_kiocb , rb_node );
2473
- if (req -> user_data < tmp -> user_data )
2474
- p = & (* p )-> rb_left ;
2475
- else
2476
- p = & (* p )-> rb_right ;
2477
- }
2478
- rb_link_node (& req -> rb_node , parent , p );
2479
- rb_insert_color (& req -> rb_node , & ctx -> cancel_tree );
2473
+ struct hlist_head * list ;
2474
+
2475
+ list = & ctx -> cancel_hash [hash_long (req -> user_data , ctx -> cancel_hash_bits )];
2476
+ hlist_add_head (& req -> hash_node , list );
2480
2477
}
2481
2478
2482
2479
static int io_poll_add (struct io_kiocb * req , const struct io_uring_sqe * sqe ,
@@ -2504,7 +2501,7 @@ static int io_poll_add(struct io_kiocb *req, const struct io_uring_sqe *sqe,
2504
2501
INIT_IO_WORK (& req -> work , io_poll_complete_work );
2505
2502
events = READ_ONCE (sqe -> poll_events );
2506
2503
poll -> events = demangle_poll (events ) | EPOLLERR | EPOLLHUP ;
2507
- RB_CLEAR_NODE (& req -> rb_node );
2504
+ INIT_HLIST_NODE (& req -> hash_node );
2508
2505
2509
2506
poll -> head = NULL ;
2510
2507
poll -> done = false;
@@ -4644,6 +4641,7 @@ static void io_ring_ctx_free(struct io_ring_ctx *ctx)
4644
4641
free_uid (ctx -> user );
4645
4642
put_cred (ctx -> creds );
4646
4643
kfree (ctx -> completions );
4644
+ kfree (ctx -> cancel_hash );
4647
4645
kmem_cache_free (req_cachep , ctx -> fallback_req );
4648
4646
kfree (ctx );
4649
4647
}
0 commit comments