Commit 80f8ea98 authored by Umang Jain's avatar Umang Jain Committed by Greg Kroah-Hartman
Browse files

staging: vchiq_core: Return -EINTR when bulk transfers are interrupted



Bulk transfers for various VCHIQ modes use mutex_lock_killable() and
wait_for_completion_killable() variations. Currently, -EAGAIN is
returned if these are interrupted by a fatal signal.

-EAGAIN may mislead the caller into thinking the operation can be
retried, while in reality, the process has received a fatal signal
and is terminating. Therefore, we should update the return value to
align with what these killable functions would return, specifically
-EINTR (Interrupted system call).

Signed-off-by: default avatarUmang Jain <umang.jain@ideasonboard.com>
Link: https://lore.kernel.org/r/20240918163100.870596-5-umang.jain@ideasonboard.com


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 72925dec
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -870,11 +870,11 @@ vchiq_bulk_transmit(struct vchiq_instance *instance, unsigned int handle, const
		}

		/*
		 * vchiq_*_bulk_transfer() may return -EAGAIN, so we need
		 * vchiq_*_bulk_transfer() may return -EINTR, so we need
		 * to implement a retry mechanism since this function is
		 * supposed to block until queued
		 */
		if (ret != -EAGAIN)
		if (ret != -EINTR)
			break;

		msleep(1);
@@ -906,11 +906,11 @@ int vchiq_bulk_receive(struct vchiq_instance *instance, unsigned int handle,
		}

		/*
		 * vchiq_*_bulk_transfer() may return -EAGAIN, so we need
		 * vchiq_*_bulk_transfer() may return -EINTR, so we need
		 * to implement a retry mechanism since this function is
		 * supposed to block until queued
		 */
		if (ret != -EAGAIN)
		if (ret != -EINTR)
			break;

		msleep(1);
+6 −6
Original line number Diff line number Diff line
@@ -2689,16 +2689,16 @@ vchiq_bulk_xfer_queue_msg_killable(struct vchiq_service *service,
		&service->bulk_tx : &service->bulk_rx;

	if (mutex_lock_killable(&service->bulk_mutex))
		return -EAGAIN;
		return -EINTR;

	if (queue->local_insert == queue->remove + VCHIQ_NUM_SERVICE_BULKS) {
		VCHIQ_SERVICE_STATS_INC(service, bulk_stalls);
		do {
			mutex_unlock(&service->bulk_mutex);
			if (wait_for_completion_killable(&service->bulk_remove_event))
				return -EAGAIN;
				return -EINTR;
			if (mutex_lock_killable(&service->bulk_mutex))
				return -EAGAIN;
				return -EINTR;
		} while (queue->local_insert == queue->remove +
				VCHIQ_NUM_SERVICE_BULKS);
	}
@@ -2729,7 +2729,7 @@ vchiq_bulk_xfer_queue_msg_killable(struct vchiq_service *service,
	 * claim it here to ensure that isn't happening
	 */
	if (mutex_lock_killable(&state->slot_mutex)) {
		status = -EAGAIN;
		status = -EINTR;
		goto cancel_bulk_error_exit;
	}

@@ -2764,7 +2764,7 @@ vchiq_bulk_xfer_queue_msg_killable(struct vchiq_service *service,
        if (bulk_waiter) {
                bulk_waiter->bulk = bulk;
		if (wait_for_completion_killable(&bulk_waiter->event))
                        status = -EAGAIN;
			status = -EINTR;
                else if (bulk_waiter->actual == VCHIQ_BULK_ACTUAL_ABORTED)
                        status = -EINVAL;
        }
@@ -3203,7 +3203,7 @@ vchiq_bulk_xfer_waiting(struct vchiq_instance *instance,
	status = 0;

	if (wait_for_completion_killable(&bulk_waiter->event))
		return -EAGAIN;
		return -EINTR;
	else if (bulk_waiter->actual == VCHIQ_BULK_ACTUAL_ABORTED)
		return -EINVAL;