Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

RDMA/irdma: Reduce iWARP QP destroy time

QP destroy is synchronous and waits for its refcnt to be decremented in
irdma_cm_node_free_cb (for iWARP) which fires after the RCU grace period
elapses.

Applications running a large number of connections are exposed to high
wait times on destroy QP for events like SIGABORT.

The long pole for this wait time is the firing of the call_rcu callback
during a CM node destroy which can be slow. It holds the QP reference
count and blocks the destroy QP from completing.

call_rcu only needs to make sure that list walkers have a reference to the
cm_node object before freeing it and thus need to wait for grace period
elapse. The rest of the connection teardown in irdma_cm_node_free_cb is
moved out of the grace period wait in irdma_destroy_connection. Also,
replace call_rcu with a simple kfree_rcu as it just needs to do a kfree on
the cm_node

Fixes: 146b9756f14c ("RDMA/irdma: Add connection manager")
Link: https://lore.kernel.org/r/20220425181703.1634-3-shiraz.saleem@intel.com
Signed-off-by: Shiraz Saleem <shiraz.saleem@intel.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>

authored by

Shiraz Saleem and committed by
Jason Gunthorpe
2df6d895 7b8943b8

+4 -6
+4 -6
drivers/infiniband/hw/irdma/cm.c
··· 2308 2308 return NULL; 2309 2309 } 2310 2310 2311 - static void irdma_cm_node_free_cb(struct rcu_head *rcu_head) 2311 + static void irdma_destroy_connection(struct irdma_cm_node *cm_node) 2312 2312 { 2313 - struct irdma_cm_node *cm_node = 2314 - container_of(rcu_head, struct irdma_cm_node, rcu_head); 2315 2313 struct irdma_cm_core *cm_core = cm_node->cm_core; 2316 2314 struct irdma_qp *iwqp; 2317 2315 struct irdma_cm_info nfo; ··· 2357 2359 } 2358 2360 2359 2361 cm_core->cm_free_ah(cm_node); 2360 - kfree(cm_node); 2361 2362 } 2362 2363 2363 2364 /** ··· 2384 2387 2385 2388 spin_unlock_irqrestore(&cm_core->ht_lock, flags); 2386 2389 2387 - /* wait for all list walkers to exit their grace period */ 2388 - call_rcu(&cm_node->rcu_head, irdma_cm_node_free_cb); 2390 + irdma_destroy_connection(cm_node); 2391 + 2392 + kfree_rcu(cm_node, rcu_head); 2389 2393 } 2390 2394 2391 2395 /**