* [PATCH V3] atmel: fix a race between fw_load and data free
@ 2015-05-15 12:32 Pan Xinhui
0 siblings, 0 replies; only message in thread
From: Pan Xinhui @ 2015-05-15 12:32 UTC (permalink / raw)
To: linux-kernel; +Cc: dmitry.torokhov, nick.dyer, mnipxh, yanmin_zhang
mxt_probe() may fail at last step, or we jsut unload mxt module soon.
the queue_work scheduled by request_firmware_nowait may run later,
and then access some data which is freed.
To handle this issue, add fw_load_completion field in mxt_data.
then we wait for it complete both in probe error path and mxt_remove().
here is the detail in probe, similar in remove.
module load: worker_thread:
mxt_probe -> mxt_initialize -> request_firmware_nowait (schedule_work)
|
sysfs_create_group (fails) mxt_config_cb -> mxt_configure_objects (may access data freed)
|
err_free_object: some cleanup work, like free(data).
Signed-off-by: xinhui.pan <xinhuix.pan@intel.com>
---
change in v3:
use wait_for_completion, avoid timeout side effect.
change in V2:
use fw_load_completion instead of statics.
fix a race both in mxt_remove and mxt_probe.
drivers/input/touchscreen/atmel_mxt_ts.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index 40b98dd..bea69da 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -313,6 +313,9 @@ struct mxt_data {
/* for config update handling */
struct completion crc_completion;
+
+ /* for fw load handling */
+ struct completion fw_load_completion;
};
static size_t mxt_obj_size(const struct mxt_object *obj)
@@ -1982,8 +1985,10 @@ static int mxt_configure_objects(struct mxt_data *data,
static void mxt_config_cb(const struct firmware *cfg, void *ctx)
{
+ struct mxt_data *data = ctx;
mxt_configure_objects(ctx, cfg);
release_firmware(cfg);
+ complete(&data->fw_load_completion);
}
static int mxt_initialize(struct mxt_data *data)
@@ -2556,6 +2561,7 @@ static int mxt_probe(struct i2c_client *client, const struct i2c_device_id *id)
init_completion(&data->bl_completion);
init_completion(&data->reset_completion);
init_completion(&data->crc_completion);
+ init_completion(&data->fw_load_completion);
error = request_threaded_irq(client->irq, NULL, mxt_interrupt,
pdata->irqflags | IRQF_ONESHOT,
@@ -2581,6 +2587,7 @@ static int mxt_probe(struct i2c_client *client, const struct i2c_device_id *id)
return 0;
err_free_object:
+ wait_for_completion(&data->fw_load_completion);
mxt_free_input_device(data);
mxt_free_object_table(data);
err_free_irq:
@@ -2594,6 +2601,7 @@ static int mxt_remove(struct i2c_client *client)
{
struct mxt_data *data = i2c_get_clientdata(client);
+ wait_for_completion(&data->fw_load_completion);
sysfs_remove_group(&client->dev.kobj, &mxt_attr_group);
free_irq(data->irq, data);
mxt_free_input_device(data);
--
1.9.1
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2015-05-14 12:34 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-05-15 12:32 [PATCH V3] atmel: fix a race between fw_load and data free Pan Xinhui
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.