mei: simplify io callback disposal

Simplify disposal of io callback by removing the callback
implicitly from its lookup list inside mei_io_cb_free

Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Tomas Winkler 2015-02-10 10:39:45 +02:00 committed by Greg Kroah-Hartman
parent 03b8d3419f
commit 928fa6664b
6 changed files with 66 additions and 108 deletions

View File

@ -196,16 +196,16 @@ int mei_amthif_read(struct mei_device *dev, struct file *file,
if (time_after(jiffies, timeout)) {
dev_dbg(dev->dev, "amthif Time out\n");
/* 15 sec for the message has expired */
list_del(&cb->list);
list_del_init(&cb->list);
rets = -ETIME;
goto free;
}
/* if the whole message will fit remove it from the list */
if (cb->buf_idx >= *offset && length >= (cb->buf_idx - *offset))
list_del(&cb->list);
list_del_init(&cb->list);
else if (cb->buf_idx > 0 && cb->buf_idx <= *offset) {
/* end of the message has been reached */
list_del(&cb->list);
list_del_init(&cb->list);
rets = 0;
goto free;
}
@ -504,26 +504,22 @@ void mei_amthif_complete(struct mei_device *dev, struct mei_cl_cb *cb)
static bool mei_clear_list(struct mei_device *dev,
const struct file *file, struct list_head *mei_cb_list)
{
struct mei_cl_cb *cb_pos = NULL;
struct mei_cl_cb *cb_next = NULL;
struct mei_cl *cl = &dev->iamthif_cl;
struct mei_cl_cb *cb, *next;
bool removed = false;
/* list all list member */
list_for_each_entry_safe(cb_pos, cb_next, mei_cb_list, list) {
list_for_each_entry_safe(cb, next, mei_cb_list, list) {
/* check if list member associated with a file */
if (file == cb_pos->file_object) {
/* remove member from the list */
list_del(&cb_pos->list);
if (file == cb->file_object) {
/* check if cb equal to current iamthif cb */
if (dev->iamthif_current_cb == cb_pos) {
if (dev->iamthif_current_cb == cb) {
dev->iamthif_current_cb = NULL;
/* send flow control to iamthif client */
mei_hbm_cl_flow_control_req(dev,
&dev->iamthif_cl);
mei_hbm_cl_flow_control_req(dev, cl);
}
/* free all allocated buffers */
mei_io_cb_free(cb_pos);
cb_pos = NULL;
mei_io_cb_free(cb);
removed = true;
}
}

View File

@ -311,13 +311,13 @@ ssize_t __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length)
mutex_lock(&dev->device_lock);
}
cb = cl->read_cb;
if (cl->reading_state != MEI_READ_COMPLETE) {
rets = 0;
goto out;
}
cb = cl->read_cb;
if (cb->status) {
rets = cb->status;
goto free;
@ -329,8 +329,8 @@ ssize_t __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length)
free:
mei_io_cb_free(cb);
cl->reading_state = MEI_IDLE;
cl->read_cb = NULL;
cl->reading_state = MEI_IDLE;
out:
mutex_unlock(&dev->device_lock);
@ -486,23 +486,7 @@ int mei_cl_disable_device(struct mei_cl_device *device)
/* Flush queues and remove any pending read */
mei_cl_flush_queues(cl);
if (cl->read_cb) {
struct mei_cl_cb *cb = NULL;
cb = mei_cl_find_read_cb(cl);
/* Remove entry from read list */
if (cb)
list_del(&cb->list);
cb = cl->read_cb;
cl->read_cb = NULL;
if (cb) {
mei_io_cb_free(cb);
cb = NULL;
}
}
mei_io_cb_free(cl->read_cb);
device->event_cb = NULL;

View File

@ -320,52 +320,6 @@ static inline bool mei_cl_cmp_id(const struct mei_cl *cl1,
(cl1->me_client_id == cl2->me_client_id);
}
/**
* __mei_io_list_flush - removes and frees cbs belonging to cl.
*
* @list: an instance of our list structure
* @cl: host client, can be NULL for flushing the whole list
* @free: whether to free the cbs
*/
static void __mei_io_list_flush(struct mei_cl_cb *list,
struct mei_cl *cl, bool free)
{
struct mei_cl_cb *cb;
struct mei_cl_cb *next;
/* enable removing everything if no cl is specified */
list_for_each_entry_safe(cb, next, &list->list, list) {
if (!cl || mei_cl_cmp_id(cl, cb->cl)) {
list_del(&cb->list);
if (free)
mei_io_cb_free(cb);
}
}
}
/**
* mei_io_list_flush - removes list entry belonging to cl.
*
* @list: An instance of our list structure
* @cl: host client
*/
void mei_io_list_flush(struct mei_cl_cb *list, struct mei_cl *cl)
{
__mei_io_list_flush(list, cl, false);
}
/**
* mei_io_list_free - removes cb belonging to cl and free them
*
* @list: An instance of our list structure
* @cl: host client
*/
static inline void mei_io_list_free(struct mei_cl_cb *list, struct mei_cl *cl)
{
__mei_io_list_flush(list, cl, true);
}
/**
* mei_io_cb_free - free mei_cb_private related memory
*
@ -376,6 +330,7 @@ void mei_io_cb_free(struct mei_cl_cb *cb)
if (cb == NULL)
return;
list_del(&cb->list);
kfree(cb->buf.data);
kfree(cb);
}
@ -398,8 +353,7 @@ struct mei_cl_cb *mei_io_cb_init(struct mei_cl *cl, enum mei_cb_file_ops type,
if (!cb)
return NULL;
mei_io_list_init(cb);
INIT_LIST_HEAD(&cb->list);
cb->file_object = fp;
cb->cl = cl;
cb->buf_idx = 0;
@ -407,6 +361,50 @@ struct mei_cl_cb *mei_io_cb_init(struct mei_cl *cl, enum mei_cb_file_ops type,
return cb;
}
/**
* __mei_io_list_flush - removes and frees cbs belonging to cl.
*
* @list: an instance of our list structure
* @cl: host client, can be NULL for flushing the whole list
* @free: whether to free the cbs
*/
static void __mei_io_list_flush(struct mei_cl_cb *list,
struct mei_cl *cl, bool free)
{
struct mei_cl_cb *cb, *next;
/* enable removing everything if no cl is specified */
list_for_each_entry_safe(cb, next, &list->list, list) {
if (!cl || mei_cl_cmp_id(cl, cb->cl)) {
list_del_init(&cb->list);
if (free)
mei_io_cb_free(cb);
}
}
}
/**
* mei_io_list_flush - removes list entry belonging to cl.
*
* @list: An instance of our list structure
* @cl: host client
*/
void mei_io_list_flush(struct mei_cl_cb *list, struct mei_cl *cl)
{
__mei_io_list_flush(list, cl, false);
}
/**
* mei_io_list_free - removes cb belonging to cl and free them
*
* @list: An instance of our list structure
* @cl: host client
*/
static inline void mei_io_list_free(struct mei_cl_cb *list, struct mei_cl *cl)
{
__mei_io_list_flush(list, cl, true);
}
/**
* mei_io_cb_alloc_buf - allocate callback buffer
*

View File

@ -639,7 +639,7 @@ static void mei_hbm_cl_res(struct mei_device *dev,
continue;
if (mei_hbm_cl_addr_equal(cl, rs)) {
list_del(&cb->list);
list_del_init(&cb->list);
break;
}
}

View File

@ -202,7 +202,6 @@ static int mei_cl_irq_disconnect_rsp(struct mei_cl *cl, struct mei_cl_cb *cb,
cl->state = MEI_FILE_DISCONNECTED;
cl->status = 0;
list_del(&cb->list);
mei_io_cb_free(cb);
return ret;
@ -320,7 +319,7 @@ static int mei_cl_irq_connect(struct mei_cl *cl, struct mei_cl_cb *cb,
if (ret) {
cl->status = ret;
cb->buf_idx = 0;
list_del(&cb->list);
list_del_init(&cb->list);
return ret;
}

View File

@ -94,7 +94,6 @@ err_unlock:
static int mei_release(struct inode *inode, struct file *file)
{
struct mei_cl *cl = file->private_data;
struct mei_cl_cb *cb;
struct mei_device *dev;
int rets = 0;
@ -118,23 +117,11 @@ static int mei_release(struct inode *inode, struct file *file)
mei_cl_unlink(cl);
/* free read cb */
cb = NULL;
if (cl->read_cb) {
cb = mei_cl_find_read_cb(cl);
/* Remove entry from read list */
if (cb)
list_del(&cb->list);
cb = cl->read_cb;
cl->read_cb = NULL;
}
mei_io_cb_free(cl->read_cb);
cl->read_cb = NULL;
file->private_data = NULL;
mei_io_cb_free(cb);
kfree(cl);
out:
mutex_unlock(&dev->device_lock);
@ -156,7 +143,6 @@ static ssize_t mei_read(struct file *file, char __user *ubuf,
size_t length, loff_t *offset)
{
struct mei_cl *cl = file->private_data;
struct mei_cl_cb *cb_pos = NULL;
struct mei_cl_cb *cb = NULL;
struct mei_device *dev;
int rets;
@ -279,13 +265,10 @@ copy_buffer:
goto out;
free:
cb_pos = mei_cl_find_read_cb(cl);
/* Remove entry from read list */
if (cb_pos)
list_del(&cb_pos->list);
mei_io_cb_free(cb);
cl->reading_state = MEI_IDLE;
cl->read_cb = NULL;
cl->reading_state = MEI_IDLE;
out:
dev_dbg(dev->dev, "end mei read rets= %d\n", rets);
mutex_unlock(&dev->device_lock);
@ -355,7 +338,6 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf,
if (time_after(jiffies, timeout) ||
cl->reading_state == MEI_READ_COMPLETE) {
*offset = 0;
list_del(&write_cb->list);
mei_io_cb_free(write_cb);
write_cb = NULL;
}
@ -367,11 +349,10 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf,
*offset = 0;
write_cb = mei_cl_find_read_cb(cl);
if (write_cb) {
list_del(&write_cb->list);
mei_io_cb_free(write_cb);
write_cb = NULL;
cl->reading_state = MEI_IDLE;
cl->read_cb = NULL;
cl->reading_state = MEI_IDLE;
}
} else if (cl->reading_state == MEI_IDLE)
*offset = 0;