diff options
author | Alexander Usyskin <alexander.usyskin@intel.com> | 2020-08-18 14:51:42 +0300 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2020-08-18 16:44:44 +0300 |
commit | 15ffa991d9cb4bd1e9cdc9caf25201c6627b5432 (patch) | |
tree | 2399590aa17d857e0ff2aeada481f8a21f706a45 /drivers/misc/mei | |
parent | f35fe5f47ed0ea532a81603cac13a259d056c077 (diff) | |
download | linux-15ffa991d9cb4bd1e9cdc9caf25201c6627b5432.tar.xz |
mei: handle tx queue flushing for vtag connections
Since multiple file pointers (fp) can be associated
with a single host client, upon close() only objects
associated with the fp has to flushed from the tx queues.
The control queues should be flushed only when all
the connections are closed and the client is disconnected.
Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com>
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Link: https://lore.kernel.org/r/20200818115147.2567012-9-tomas.winkler@intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/misc/mei')
-rw-r--r-- | drivers/misc/mei/client.c | 23 |
1 files changed, 13 insertions, 10 deletions
diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c index 3904fce18261..d5c3f7d54634 100644 --- a/drivers/misc/mei/client.c +++ b/drivers/misc/mei/client.c @@ -429,14 +429,16 @@ static void mei_io_list_flush_cl(struct list_head *head, * * @head: An instance of our list structure * @cl: host client + * @fp: file pointer (matching cb file object), may be NULL */ static void mei_io_tx_list_free_cl(struct list_head *head, - const struct mei_cl *cl) + const struct mei_cl *cl, + const struct file *fp) { struct mei_cl_cb *cb, *next; list_for_each_entry_safe(cb, next, head, list) { - if (cl == cb->cl) + if (cl == cb->cl && (!fp || fp == cb->fp)) mei_tx_cb_dequeue(cb); } } @@ -574,13 +576,14 @@ int mei_cl_flush_queues(struct mei_cl *cl, const struct file *fp) dev = cl->dev; cl_dbg(dev, cl, "remove list entry belonging to cl\n"); - mei_io_tx_list_free_cl(&cl->dev->write_list, cl); - mei_io_tx_list_free_cl(&cl->dev->write_waiting_list, cl); - mei_io_list_flush_cl(&cl->dev->ctrl_wr_list, cl); - mei_io_list_flush_cl(&cl->dev->ctrl_rd_list, cl); - /* free pending cb only in final flush */ - if (!fp) + mei_io_tx_list_free_cl(&cl->dev->write_list, cl, fp); + mei_io_tx_list_free_cl(&cl->dev->write_waiting_list, cl, fp); + /* free pending and control cb only in final flush */ + if (!fp) { + mei_io_list_flush_cl(&cl->dev->ctrl_wr_list, cl); + mei_io_list_flush_cl(&cl->dev->ctrl_rd_list, cl); mei_cl_free_pending(cl); + } spin_lock(&cl->rd_completed_lock); mei_io_list_free_fp(&cl->rd_completed, fp); spin_unlock(&cl->rd_completed_lock); @@ -798,8 +801,8 @@ static void mei_cl_set_disconnected(struct mei_cl *cl) return; cl->state = MEI_FILE_DISCONNECTED; - mei_io_tx_list_free_cl(&dev->write_list, cl); - mei_io_tx_list_free_cl(&dev->write_waiting_list, cl); + mei_io_tx_list_free_cl(&dev->write_list, cl, NULL); + mei_io_tx_list_free_cl(&dev->write_waiting_list, cl, NULL); mei_io_list_flush_cl(&dev->ctrl_rd_list, cl); mei_io_list_flush_cl(&dev->ctrl_wr_list, cl); mei_cl_wake_all(cl); |