net/rds: replace tasklets with workqueue

Convert the deprecated send and receive completion tasklets in
net/rds/ib to BH work items queued on system_bh_wq.

In rds_ib_conn_path_shutdown(), replace tasklet_kill() with
disable_work_sync(), and call enable_work() after destroying the CQs so
the work items can be used again when the connection reconnects.

Signed-off-by: Sunny Tiwari <sunnytiwari@google.com>
Reviewed-by: Allison Henderson <achender@kernel.org>
Link: https://patch.msgid.link/20cbfc32678019daadd3c67fd75262b8264aa180.1790178801.git.sunnytiwari@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Sunny Tiwari 2026-09-24 06:26:11 +00:00 committed by Jakub Kicinski
parent ab61766635
commit 5ccac2330d
2 changed files with 17 additions and 16 deletions

View File

@ -159,8 +159,8 @@ struct rds_ib_connection {
atomic_t i_fastreg_inuse_count;
/* interrupt handling */
struct tasklet_struct i_send_tasklet;
struct tasklet_struct i_recv_tasklet;
struct work_struct i_send_work;
struct work_struct i_recv_work;
/* tx */
struct rds_ib_work_ring i_send_ring;

View File

@ -253,7 +253,7 @@ static void rds_ib_cq_comp_handler_recv(struct ib_cq *cq, void *context)
rds_ib_stats_inc(s_ib_evt_handler_call);
tasklet_schedule(&ic->i_recv_tasklet);
queue_work(system_bh_wq, &ic->i_recv_work);
}
static void poll_scq(struct rds_ib_connection *ic, struct ib_cq *cq,
@ -279,9 +279,9 @@ static void poll_scq(struct rds_ib_connection *ic, struct ib_cq *cq,
}
}
static void rds_ib_tasklet_fn_send(unsigned long data)
static void rds_ib_send_worker(struct work_struct *work)
{
struct rds_ib_connection *ic = (struct rds_ib_connection *)data;
struct rds_ib_connection *ic = from_work(ic, work, i_send_work);
struct rds_connection *conn = ic->conn;
rds_ib_stats_inc(s_ib_tasklet_call);
@ -319,9 +319,9 @@ static void poll_rcq(struct rds_ib_connection *ic, struct ib_cq *cq,
}
}
static void rds_ib_tasklet_fn_recv(unsigned long data)
static void rds_ib_recv_worker(struct work_struct *work)
{
struct rds_ib_connection *ic = (struct rds_ib_connection *)data;
struct rds_ib_connection *ic = from_work(ic, work, i_recv_work);
struct rds_connection *conn = ic->conn;
struct rds_ib_device *rds_ibdev = ic->rds_ibdev;
struct rds_ib_ack_state state;
@ -381,7 +381,7 @@ static void rds_ib_cq_comp_handler_send(struct ib_cq *cq, void *context)
rds_ib_stats_inc(s_ib_evt_handler_call);
tasklet_schedule(&ic->i_send_tasklet);
queue_work(system_bh_wq, &ic->i_send_work);
}
static inline int ibdev_get_unused_vector(struct rds_ib_device *rds_ibdev)
@ -1099,12 +1099,12 @@ void rds_ib_conn_path_shutdown(struct rds_conn_path *cp)
while (!wait_event_timeout(rds_ib_ring_empty_wait,
rds_ib_conn_path_shutdown_check_wait(cp) == 0,
msecs_to_jiffies(1000))) {
tasklet_schedule(&ic->i_send_tasklet);
tasklet_schedule(&ic->i_recv_tasklet);
queue_work(system_bh_wq, &ic->i_send_work);
queue_work(system_bh_wq, &ic->i_recv_work);
}
tasklet_kill(&ic->i_send_tasklet);
tasklet_kill(&ic->i_recv_tasklet);
disable_work_sync(&ic->i_send_work);
disable_work_sync(&ic->i_recv_work);
atomic_set(&ic->i_cq_quiesce, 1);
@ -1123,6 +1123,9 @@ void rds_ib_conn_path_shutdown(struct rds_conn_path *cp)
ib_destroy_cq(ic->i_recv_cq);
}
enable_work(&ic->i_send_work);
enable_work(&ic->i_recv_work);
if (ic->rds_ibdev) {
/* then free the resources that ib callbacks use */
if (ic->i_send_hdrs) {
@ -1234,10 +1237,8 @@ int rds_ib_conn_alloc(struct rds_connection *conn, gfp_t gfp)
}
INIT_LIST_HEAD(&ic->ib_node);
tasklet_init(&ic->i_send_tasklet, rds_ib_tasklet_fn_send,
(unsigned long)ic);
tasklet_init(&ic->i_recv_tasklet, rds_ib_tasklet_fn_recv,
(unsigned long)ic);
INIT_WORK(&ic->i_send_work, rds_ib_send_worker);
INIT_WORK(&ic->i_recv_work, rds_ib_recv_worker);
mutex_init(&ic->i_recv_mutex);
#ifndef KERNEL_HAS_ATOMIC64
spin_lock_init(&ic->i_ack_lock);