Commit b12fdf7d authored by Zachary Warren's avatar Zachary Warren Committed by Greg Kroah-Hartman

staging: unisys: rework signal remove/insert to avoid sparse lock warnings

Avoids the following warnings from sparse:
visorchannel_funcs.c:457:9: warning:
 context imbalance in 'visorchannel_signalremove' - different lock contexts for basic block
visorchannel_funcs.c:512:9: warning:
 context imbalance in 'visorchannel_signalinsert' - different lock contexts for basic

These warnings are false positives. Sparse can't track conditional contexts. The change
puts the lock/unlock into the same context by splitting the insert/remove functions each
into a wrapper function that does locking if necessary and an inner function that does the
insert/remove operation.
Signed-off-by: default avatarZachary Warren <conflatulence@gmail.com>
Acked-by: default avatarBenjamin Romer <benjamin.romer@unisys.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent c1f79c74
...@@ -411,27 +411,21 @@ safe_sig_queue_validate(struct signal_queue_header *psafe_sqh, ...@@ -411,27 +411,21 @@ safe_sig_queue_validate(struct signal_queue_header *psafe_sqh,
return 1; return 1;
} /* end safe_sig_queue_validate */ } /* end safe_sig_queue_validate */
BOOL static BOOL
visorchannel_signalremove(struct visorchannel *channel, u32 queue, void *msg) signalremove_inner(struct visorchannel *channel, u32 queue, void *msg)
{ {
BOOL rc = FALSE;
struct signal_queue_header sig_hdr; struct signal_queue_header sig_hdr;
if (channel->needs_lock)
spin_lock(&channel->remove_lock);
if (!sig_read_header(channel, queue, &sig_hdr)) { if (!sig_read_header(channel, queue, &sig_hdr)) {
rc = FALSE; return FALSE;
goto cleanup;
}
if (sig_hdr.head == sig_hdr.tail) {
rc = FALSE; /* no signals to remove */
goto cleanup;
} }
if (sig_hdr.head == sig_hdr.tail)
return FALSE; /* no signals to remove */
sig_hdr.tail = (sig_hdr.tail + 1) % sig_hdr.max_slots; sig_hdr.tail = (sig_hdr.tail + 1) % sig_hdr.max_slots;
if (!sig_read_data(channel, queue, &sig_hdr, sig_hdr.tail, msg)) { if (!sig_read_data(channel, queue, &sig_hdr, sig_hdr.tail, msg)) {
ERRDRV("sig_read_data failed: (status=%d)\n", rc); ERRDRV("sig_read_data failed\n");
goto cleanup; return FALSE;
} }
sig_hdr.num_received++; sig_hdr.num_received++;
...@@ -440,53 +434,54 @@ visorchannel_signalremove(struct visorchannel *channel, u32 queue, void *msg) ...@@ -440,53 +434,54 @@ visorchannel_signalremove(struct visorchannel *channel, u32 queue, void *msg)
*/ */
mb(); /* required for channel synch */ mb(); /* required for channel synch */
if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, tail)) { if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, tail)) {
ERRDRV("visor_memregion_write of Tail failed: (status=%d)\n", ERRDRV("visor_memregion_write of Tail failed\n");
rc); return FALSE;
goto cleanup;
} }
if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, num_received)) { if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, num_received)) {
ERRDRV("visor_memregion_write of NumSignalsReceived failed: (status=%d)\n", ERRDRV("visor_memregion_write of NumSignalsReceived failed\n");
rc); return FALSE;
goto cleanup;
} }
rc = TRUE; return TRUE;
cleanup: }
if (channel->needs_lock)
BOOL
visorchannel_signalremove(struct visorchannel *channel, u32 queue, void *msg)
{
BOOL rc;
if (channel->needs_lock) {
spin_lock(&channel->remove_lock);
rc = signalremove_inner(channel, queue, msg);
spin_unlock(&channel->remove_lock); spin_unlock(&channel->remove_lock);
} else {
rc = signalremove_inner(channel, queue, msg);
}
return rc; return rc;
} }
EXPORT_SYMBOL_GPL(visorchannel_signalremove); EXPORT_SYMBOL_GPL(visorchannel_signalremove);
BOOL static BOOL
visorchannel_signalinsert(struct visorchannel *channel, u32 queue, void *msg) signalinsert_inner(struct visorchannel *channel, u32 queue, void *msg)
{ {
BOOL rc = FALSE;
struct signal_queue_header sig_hdr; struct signal_queue_header sig_hdr;
if (channel->needs_lock)
spin_lock(&channel->insert_lock);
if (!sig_read_header(channel, queue, &sig_hdr)) { if (!sig_read_header(channel, queue, &sig_hdr)) {
rc = FALSE; return FALSE;
goto cleanup;
} }
sig_hdr.head = ((sig_hdr.head + 1) % sig_hdr.max_slots); sig_hdr.head = ((sig_hdr.head + 1) % sig_hdr.max_slots);
if (sig_hdr.head == sig_hdr.tail) { if (sig_hdr.head == sig_hdr.tail) {
sig_hdr.num_overflows++; sig_hdr.num_overflows++;
if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, num_overflows)) { if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, num_overflows))
ERRDRV("visor_memregion_write of NumOverflows failed: (status=%d)\n", ERRDRV("visor_memregion_write of NumOverflows failed\n");
rc);
goto cleanup; return FALSE;
}
rc = FALSE;
goto cleanup;
} }
if (!sig_write_data(channel, queue, &sig_hdr, sig_hdr.head, msg)) { if (!sig_write_data(channel, queue, &sig_hdr, sig_hdr.head, msg)) {
ERRDRV("sig_write_data failed: (status=%d)\n", rc); ERRDRV("sig_write_data failed\n");
goto cleanup; return FALSE;
} }
sig_hdr.num_sent++; sig_hdr.num_sent++;
...@@ -495,19 +490,29 @@ visorchannel_signalinsert(struct visorchannel *channel, u32 queue, void *msg) ...@@ -495,19 +490,29 @@ visorchannel_signalinsert(struct visorchannel *channel, u32 queue, void *msg)
*/ */
mb(); /* required for channel synch */ mb(); /* required for channel synch */
if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, head)) { if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, head)) {
ERRDRV("visor_memregion_write of Head failed: (status=%d)\n", ERRDRV("visor_memregion_write of Head failed\n");
rc); return FALSE;
goto cleanup;
} }
if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, num_sent)) { if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, num_sent)) {
ERRDRV("visor_memregion_write of NumSignalsSent failed: (status=%d)\n", ERRDRV("visor_memregion_write of NumSignalsSent failed\n");
rc); return FALSE;
goto cleanup;
} }
rc = TRUE;
cleanup: return TRUE;
if (channel->needs_lock) }
BOOL
visorchannel_signalinsert(struct visorchannel *channel, u32 queue, void *msg)
{
BOOL rc;
if (channel->needs_lock) {
spin_lock(&channel->insert_lock);
rc = signalinsert_inner(channel, queue, msg);
spin_unlock(&channel->insert_lock); spin_unlock(&channel->insert_lock);
} else {
rc = signalinsert_inner(channel, queue, msg);
}
return rc; return rc;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment