[char-misc-next 16/18] mei: simplify io callback disposal

From: Tomas Winkler
Date: Tue Feb 10 2015 - 03:41:52 EST


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@xxxxxxxxx>
---
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 830a3facbb2b..f28eed12e7ab 100644
--- a/drivers/misc/mei/client.c
+++ b/drivers/misc/mei/client.c
@@ -321,6 +321,47 @@ static inline bool mei_cl_cmp_id(const struct mei_cl *cl1,
}

/**
+ * 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.
*
* @list: an instance of our list structure
@@ -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
*
@@ -367,47 +406,6 @@ static inline void mei_io_list_free(struct mei_cl_cb *list, struct mei_cl *cl)
}

/**
- * 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
*
* @cb: io callback structure
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 @@ 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;
--
1.9.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/