mei: bus: fix RX event scheduling
authorTomas Winkler <tomas.winkler@intel.com>
Sun, 7 Feb 2016 21:35:30 +0000 (23:35 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 7 Feb 2016 22:47:20 +0000 (14:47 -0800)
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 <tomas.winkler@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/misc/mei/bus.c
drivers/misc/mei/client.c
drivers/misc/mei/mei_dev.h

index 0b05aa9387996484759e748831eba5304ac3a409..a40d8e24ecda4c52129065386c532bdb7f906892 100644 (file)
@@ -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;
 }
 
 /**
index 32991684563b867ea034aff4d6974cbd4bea97ba..574f7394fb2b4c86048402b4db6ba25621230cff 100644 (file)
@@ -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:
index 81901967911d90159e09e02e52cc4d4cdcceb04f..be97b8f2a8838092fce1d260794a5c1391095f90 100644 (file)
@@ -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);