summaryrefslogtreecommitdiff
path: root/drivers/misc/mei/bus.c
diff options
context:
space:
mode:
authorAlexander Usyskin <alexander.usyskin@intel.com>2018-02-25 20:07:05 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2018-03-14 19:33:13 +0100
commitaf336cabe08363ba8493e7d7e5d070353eb30caa (patch)
tree003025b642d6dcfab2a2f5ba220ce69ee69def65 /drivers/misc/mei/bus.c
parent257355a44b9929e55d6fd47bfff66971dc4de948 (diff)
mei: limit the number of queued writes
Limit the number of queued writes per client. Writes above this threshold are blocked till place in the transmit queue is available. The limit is configurable via sysfs and defaults to 50. The implementation should provide blocking I/O behavior. Prior to this change one would end up in the hands of OOM. Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com> Signed-off-by: Tomas Winkler <tomas.winkler@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/misc/mei/bus.c')
-rw-r--r--drivers/misc/mei/bus.c17
1 files changed, 17 insertions, 0 deletions
diff --git a/drivers/misc/mei/bus.c b/drivers/misc/mei/bus.c
index 1dacc820bd7f..b1133739fb4b 100644
--- a/drivers/misc/mei/bus.c
+++ b/drivers/misc/mei/bus.c
@@ -74,6 +74,23 @@ ssize_t __mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length,
goto out;
}
+ while (cl->tx_cb_queued >= bus->tx_queue_limit) {
+ mutex_unlock(&bus->device_lock);
+ rets = wait_event_interruptible(cl->tx_wait,
+ cl->writing_state == MEI_WRITE_COMPLETE ||
+ (!mei_cl_is_connected(cl)));
+ mutex_lock(&bus->device_lock);
+ if (rets) {
+ if (signal_pending(current))
+ rets = -EINTR;
+ goto out;
+ }
+ if (!mei_cl_is_connected(cl)) {
+ rets = -ENODEV;
+ goto out;
+ }
+ }
+
cb = mei_cl_alloc_cb(cl, length, MEI_FOP_WRITE, NULL);
if (!cb) {
rets = -ENOMEM;