Skip to content

Commit

Permalink
mei: consume flow control on the first chunk of writing
Browse files Browse the repository at this point in the history
Consume the write flow control on the first chunk of the write instead
of on the buffer completion.
We can safely assume that the consequent chunks have the flow control
granted.

This addresses two issues:

1. Blocks other callbacks from the same client riding on the client's
flow control and prevents interleaving of messages as FW cannot distinguish
between two messages from the same client.

2. Fixes single buffer flow control arbitration in a clean way, without
connection/disconnection book keeping

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>
  • Loading branch information
Alexander Usyskin authored and Greg Kroah-Hartman committed May 24, 2015
1 parent 292f82c commit b8b7303
Showing 1 changed file with 14 additions and 14 deletions.
28 changes: 14 additions & 14 deletions drivers/misc/mei/client.c
Original file line number Diff line number Diff line change
Expand Up @@ -755,9 +755,6 @@ void mei_cl_set_disconnected(struct mei_cl *cl)
if (!WARN_ON(cl->me_cl->connect_count == 0))
cl->me_cl->connect_count--;

if (cl->me_cl->connect_count == 0)
cl->me_cl->mei_flow_ctrl_creds = 0;

mei_me_cl_put(cl->me_cl);
cl->me_cl = NULL;
}
Expand Down Expand Up @@ -1272,6 +1269,7 @@ int mei_cl_irq_write(struct mei_cl *cl, struct mei_cl_cb *cb,
u32 msg_slots;
int slots;
int rets;
bool first_chunk;

if (WARN_ON(!cl || !cl->dev))
return -ENODEV;
Expand All @@ -1280,7 +1278,9 @@ int mei_cl_irq_write(struct mei_cl *cl, struct mei_cl_cb *cb,

buf = &cb->buf;

rets = mei_cl_flow_ctrl_creds(cl);
first_chunk = cb->buf_idx == 0;

rets = first_chunk ? mei_cl_flow_ctrl_creds(cl) : 1;
if (rets < 0)
return rets;

Expand Down Expand Up @@ -1327,12 +1327,14 @@ int mei_cl_irq_write(struct mei_cl *cl, struct mei_cl_cb *cb,
cb->buf_idx += mei_hdr.length;
cb->completed = mei_hdr.msg_complete == 1;

if (mei_hdr.msg_complete) {
if (first_chunk) {
if (mei_cl_flow_ctrl_reduce(cl))
return -EIO;
list_move_tail(&cb->list, &dev->write_waiting_list.list);
}

if (mei_hdr.msg_complete)
list_move_tail(&cb->list, &dev->write_waiting_list.list);

return 0;
}

Expand Down Expand Up @@ -1411,21 +1413,19 @@ int mei_cl_write(struct mei_cl *cl, struct mei_cl_cb *cb, bool blocking)
if (rets)
goto err;

rets = mei_cl_flow_ctrl_reduce(cl);
if (rets)
goto err;

cl->writing_state = MEI_WRITING;
cb->buf_idx = mei_hdr.length;
cb->completed = mei_hdr.msg_complete == 1;

out:
if (mei_hdr.msg_complete) {
rets = mei_cl_flow_ctrl_reduce(cl);
if (rets < 0)
goto err;

if (mei_hdr.msg_complete)
list_add_tail(&cb->list, &dev->write_waiting_list.list);
} else {
else
list_add_tail(&cb->list, &dev->write_list.list);
}


if (blocking && cl->writing_state != MEI_WRITE_COMPLETE) {

Expand Down

0 comments on commit b8b7303

Please sign in to comment.