From 928fa6664b362aad70c16f04483414f60743e15e Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Tue, 10 Feb 2015 10:39:45 +0200 Subject: [PATCH] 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 Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/amthif.c | 24 ++++------ drivers/misc/mei/bus.c | 22 ++------- drivers/misc/mei/client.c | 88 ++++++++++++++++++------------------ drivers/misc/mei/hbm.c | 2 +- drivers/misc/mei/interrupt.c | 3 +- drivers/misc/mei/main.c | 29 ++---------- 6 files changed, 63 insertions(+), 105 deletions(-) diff --git a/drivers/misc/mei/amthif.c b/drivers/misc/mei/amthif.c index 3fdd22395b9f..7b6ed0bbfc9c 100644 --- a/drivers/misc/mei/amthif.c +++ b/drivers/misc/mei/amthif.c @@ -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; } } diff --git a/drivers/misc/mei/bus.c b/drivers/misc/mei/bus.c index 3e6ffed9402a..b5385372693d 100644 --- a/drivers/misc/mei/bus.c +++ b/drivers/misc/mei/bus.c @@ -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; diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c index e263c0713a6d..624bf0182a50 100644 --- a/drivers/misc/mei/client.c +++ b/drivers/misc/mei/client.c @@ -320,6 +320,47 @@ static inline bool mei_cl_cmp_id(const struct mei_cl *cl1, (cl1->me_client_id == cl2->me_client_id); } +/** + * mei_io_cb_free - free mei_cb_private related memory + * + * @cb: mei callback struct + */ +void mei_io_cb_free(struct mei_cl_cb *cb) +{ + if (cb == NULL) + return; + + list_del(&cb->list); + kfree(cb->buf.data); + kfree(cb); +} + +/** + * mei_io_cb_init - allocate and initialize io callback + * + * @cl: mei client + * @type: operation type + * @fp: pointer to file structure + * + * Return: mei_cl_cb pointer or NULL; + */ +struct mei_cl_cb *mei_io_cb_init(struct mei_cl *cl, enum mei_cb_file_ops type, + struct file *fp) +{ + struct mei_cl_cb *cb; + + cb = kzalloc(sizeof(struct mei_cl_cb), GFP_KERNEL); + if (!cb) + return NULL; + + INIT_LIST_HEAD(&cb->list); + cb->file_object = fp; + cb->cl = cl; + cb->buf_idx = 0; + cb->fop_type = type; + return cb; +} + /** * __mei_io_list_flush - removes and frees cbs belonging to cl. * @@ -330,13 +371,12 @@ static inline bool mei_cl_cmp_id(const struct mei_cl *cl1, 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; + 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(&cb->list); + list_del_init(&cb->list); if (free) mei_io_cb_free(cb); } @@ -354,7 +394,6 @@ 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 * @@ -366,47 +405,6 @@ 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 - * - * @cb: mei callback struct - */ -void mei_io_cb_free(struct mei_cl_cb *cb) -{ - if (cb == NULL) - return; - - kfree(cb->buf.data); - kfree(cb); -} - -/** - * mei_io_cb_init - allocate and initialize io callback - * - * @cl: mei client - * @type: operation type - * @fp: pointer to file structure - * - * Return: mei_cl_cb pointer or NULL; - */ -struct mei_cl_cb *mei_io_cb_init(struct mei_cl *cl, enum mei_cb_file_ops type, - struct file *fp) -{ - struct mei_cl_cb *cb; - - cb = kzalloc(sizeof(struct mei_cl_cb), GFP_KERNEL); - if (!cb) - return NULL; - - mei_io_list_init(cb); - - cb->file_object = fp; - cb->cl = cl; - cb->buf_idx = 0; - cb->fop_type = type; - return cb; -} - /** * mei_io_cb_alloc_buf - allocate callback buffer * diff --git a/drivers/misc/mei/hbm.c b/drivers/misc/mei/hbm.c index 2c581dcaf3b1..58da92565c5e 100644 --- a/drivers/misc/mei/hbm.c +++ b/drivers/misc/mei/hbm.c @@ -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; } } diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c index 60469a0053bb..1e2f3c774853 100644 --- a/drivers/misc/mei/interrupt.c +++ b/drivers/misc/mei/interrupt.c @@ -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; } diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c index 10fc3a6a1574..c34853be963f 100644 --- a/drivers/misc/mei/main.c +++ b/drivers/misc/mei/main.c @@ -94,7 +94,6 @@ static int mei_open(struct inode *inode, struct file *file) 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 @@ static ssize_t mei_read(struct file *file, char __user *ubuf, 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; -- GitLab