From a1f9ae2bd264e3aed95aacd0102bd22a0422b8d1 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Sun, 7 Feb 2016 23:35:30 +0200 Subject: [PATCH] mei: bus: fix RX event scheduling In this particular case this more correct and safer to check if the RX event is set in the event mask rather than query waitqueue_active Since the check is already performed in the mei_cl_bus_rx_event function, it is just required to check for its return value. Second, since we don't have exclusive waiter wake_up_interruptible_all is not used correctly here. Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/bus.c | 13 +++++++++---- drivers/misc/mei/client.c | 6 ++---- drivers/misc/mei/mei_dev.h | 2 +- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/drivers/misc/mei/bus.c b/drivers/misc/mei/bus.c index 0b05aa938799..a40d8e24ecda 100644 --- a/drivers/misc/mei/bus.c +++ b/drivers/misc/mei/bus.c @@ -252,23 +252,28 @@ void mei_cl_bus_notify_event(struct mei_cl *cl) } /** - * mei_cl_bus_rx_event - schedule rx evenet + * mei_cl_bus_rx_event - schedule rx event * * @cl: host client + * + * Return: true if event was scheduled + * false if the client is not waiting for event */ -void mei_cl_bus_rx_event(struct mei_cl *cl) +bool mei_cl_bus_rx_event(struct mei_cl *cl) { struct mei_cl_device *cldev = cl->cldev; if (!cldev || !cldev->event_cb) - return; + return false; if (!(cldev->events_mask & BIT(MEI_CL_EVENT_RX))) - return; + return false; set_bit(MEI_CL_EVENT_RX, &cldev->events); schedule_work(&cldev->event_work); + + return true; } /** diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c index 32991684563b..574f7394fb2b 100644 --- a/drivers/misc/mei/client.c +++ b/drivers/misc/mei/client.c @@ -1735,10 +1735,8 @@ void mei_cl_complete(struct mei_cl *cl, struct mei_cl_cb *cb) case MEI_FOP_READ: list_add_tail(&cb->list, &cl->rd_completed); - if (waitqueue_active(&cl->rx_wait)) - wake_up_interruptible_all(&cl->rx_wait); - else - mei_cl_bus_rx_event(cl); + if (!mei_cl_bus_rx_event(cl)) + wake_up_interruptible(&cl->rx_wait); break; case MEI_FOP_CONNECT: diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h index 81901967911d..be97b8f2a883 100644 --- a/drivers/misc/mei/mei_dev.h +++ b/drivers/misc/mei/mei_dev.h @@ -316,7 +316,7 @@ void mei_cl_bus_dev_fixup(struct mei_cl_device *dev); ssize_t __mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length, bool blocking); ssize_t __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length); -void mei_cl_bus_rx_event(struct mei_cl *cl); +bool mei_cl_bus_rx_event(struct mei_cl *cl); void mei_cl_bus_notify_event(struct mei_cl *cl); void mei_cl_bus_remove_devices(struct mei_device *bus); int mei_cl_bus_init(void); -- 2.11.0