Skip to content

Commit c22502c

Browse files
Umang Jaingregkh
authored andcommitted
staging: vchiq_core: Bubble up wait_event_interruptible() return value
wait_event_interruptible() returns if the condition evaluates to true it receives a signal. However, the current code always assume that the wait_event_interruptible() returns only when the event is fired. This should not be the case as wait_event_interruptible() can return on receiving a signal (with -ERESTARTSYS as return value). We should consider this and bubble up the return value of wait_event_interruptible() to exactly know if the wait has failed and error out. This will also help to properly stop kthreads in the subsequent patch. Meanwhile at it, remote_wait_event() is modified to return 0 on success, and an error code (from wait_event_interruptible()) on failure. The return value is now checked for remote_wait_event() calls. Signed-off-by: Umang Jain <[email protected]> Tested-by: Stefan Wahren <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent d3401ce commit c22502c

File tree

1 file changed

+24
-7
lines changed
  • drivers/staging/vc04_services/interface/vchiq_arm

1 file changed

+24
-7
lines changed

drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -501,24 +501,29 @@ remote_event_create(wait_queue_head_t *wq, struct remote_event *event)
501501
* routines where switched to the "interruptible" family of functions, as the
502502
* former was deemed unjustified and the use "killable" set all VCHIQ's
503503
* threads in D state.
504+
*
505+
* Returns: 0 on success, a negative error code on failure
504506
*/
505507
static inline int
506508
remote_event_wait(wait_queue_head_t *wq, struct remote_event *event)
507509
{
510+
int ret = 0;
511+
508512
if (!event->fired) {
509513
event->armed = 1;
510514
dsb(sy);
511-
if (wait_event_interruptible(*wq, event->fired)) {
515+
ret = wait_event_interruptible(*wq, event->fired);
516+
if (ret) {
512517
event->armed = 0;
513-
return 0;
518+
return ret;
514519
}
515520
event->armed = 0;
516521
/* Ensure that the peer sees that we are not waiting (armed == 0). */
517522
wmb();
518523
}
519524

520525
event->fired = 0;
521-
return 1;
526+
return ret;
522527
}
523528

524529
/*
@@ -1140,14 +1145,17 @@ queue_message_sync(struct vchiq_state *state, struct vchiq_service *service,
11401145
struct vchiq_header *header;
11411146
ssize_t callback_result;
11421147
int svc_fourcc;
1148+
int ret;
11431149

11441150
local = state->local;
11451151

11461152
if (VCHIQ_MSG_TYPE(msgid) != VCHIQ_MSG_RESUME &&
11471153
mutex_lock_killable(&state->sync_mutex))
11481154
return -EAGAIN;
11491155

1150-
remote_event_wait(&state->sync_release_event, &local->sync_release);
1156+
ret = remote_event_wait(&state->sync_release_event, &local->sync_release);
1157+
if (ret)
1158+
return ret;
11511159

11521160
/* Ensure that reads don't overtake the remote_event_wait. */
11531161
rmb();
@@ -1929,13 +1937,16 @@ slot_handler_func(void *v)
19291937
{
19301938
struct vchiq_state *state = v;
19311939
struct vchiq_shared_state *local = state->local;
1940+
int ret;
19321941

19331942
DEBUG_INITIALISE(local);
19341943

19351944
while (1) {
19361945
DEBUG_COUNT(SLOT_HANDLER_COUNT);
19371946
DEBUG_TRACE(SLOT_HANDLER_LINE);
1938-
remote_event_wait(&state->trigger_event, &local->trigger);
1947+
ret = remote_event_wait(&state->trigger_event, &local->trigger);
1948+
if (ret)
1949+
return ret;
19391950

19401951
/* Ensure that reads don't overtake the remote_event_wait. */
19411952
rmb();
@@ -1966,6 +1977,7 @@ recycle_func(void *v)
19661977
struct vchiq_shared_state *local = state->local;
19671978
u32 *found;
19681979
size_t length;
1980+
int ret;
19691981

19701982
length = sizeof(*found) * BITSET_SIZE(VCHIQ_MAX_SERVICES);
19711983

@@ -1975,7 +1987,9 @@ recycle_func(void *v)
19751987
return -ENOMEM;
19761988

19771989
while (1) {
1978-
remote_event_wait(&state->recycle_event, &local->recycle);
1990+
ret = remote_event_wait(&state->recycle_event, &local->recycle);
1991+
if (ret)
1992+
return ret;
19791993

19801994
process_free_queue(state, found, length);
19811995
}
@@ -1992,14 +2006,17 @@ sync_func(void *v)
19922006
(struct vchiq_header *)SLOT_DATA_FROM_INDEX(state,
19932007
state->remote->slot_sync);
19942008
int svc_fourcc;
2009+
int ret;
19952010

19962011
while (1) {
19972012
struct vchiq_service *service;
19982013
int msgid, size;
19992014
int type;
20002015
unsigned int localport, remoteport;
20012016

2002-
remote_event_wait(&state->sync_trigger_event, &local->sync_trigger);
2017+
ret = remote_event_wait(&state->sync_trigger_event, &local->sync_trigger);
2018+
if (ret)
2019+
return ret;
20032020

20042021
/* Ensure that reads don't overtake the remote_event_wait. */
20052022
rmb();

0 commit comments

Comments
 (0)