Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 07bf9627 authored by Andrew Boyer's avatar Andrew Boyer Committed by Doug Ledford
Browse files

IB/rxe: Wait for tasklets to finish before tearing down QP



The system may crash when a malformed request is received and
the error is detected by the responder.

NodeA: $ ibv_rc_pingpong -g 0 -d rxe0 -i 1 -n 1 -s 50000
NodeB: $ ibv_rc_pingpong -g 0 -d rxe0 -i 1 -n 1 -s 1024 <NodeA_ip>

The responder generates a receive error on node B since the incoming
SEND is oversized. If the client tears down the QP before the responder
or the completer finish running, a page fault may occur.

The fix makes the destroy operation spin until the tasks complete, which
appears to be original intent of the design.

Signed-off-by: default avatarAndrew Boyer <andrew.boyer@dell.com>
Reviewed-by: default avatarYuval Shaia <yuval.shaia@oracle.com>
Signed-off-by: default avatarDoug Ledford <dledford@redhat.com>
parent 5407f530
Loading
Loading
Loading
Loading
+19 −0
Original line number Diff line number Diff line
@@ -121,6 +121,7 @@ int rxe_init_task(void *obj, struct rxe_task *task,
	task->arg	= arg;
	task->func	= func;
	snprintf(task->name, sizeof(task->name), "%s", name);
	task->destroyed	= false;

	tasklet_init(&task->tasklet, rxe_do_task, (unsigned long)task);

@@ -132,11 +133,29 @@ int rxe_init_task(void *obj, struct rxe_task *task,

void rxe_cleanup_task(struct rxe_task *task)
{
	unsigned long flags;
	bool idle;

	/*
	 * Mark the task, then wait for it to finish. It might be
	 * running in a non-tasklet (direct call) context.
	 */
	task->destroyed = true;

	do {
		spin_lock_irqsave(&task->state_lock, flags);
		idle = (task->state == TASK_STATE_START);
		spin_unlock_irqrestore(&task->state_lock, flags);
	} while (!idle);

	tasklet_kill(&task->tasklet);
}

void rxe_run_task(struct rxe_task *task, int sched)
{
	if (task->destroyed)
		return;

	if (sched)
		tasklet_schedule(&task->tasklet);
	else
+1 −0
Original line number Diff line number Diff line
@@ -54,6 +54,7 @@ struct rxe_task {
	int			(*func)(void *arg);
	int			ret;
	char			name[16];
	bool			destroyed;
};

/*