Commit ff102ea9 authored by Dmitry Torokhov's avatar Dmitry Torokhov Committed by Len Brown

ACPI: video - remove unsafe uses of list_for_each_safe()

list_for_each_safe() only protects list from list alterations
performed by the same thread. One still needs to implement
proper locking when list is being accessed from several threads.
Signed-off-by: default avatarDmitry Torokhov <dtor@mail.ru>
Acked-by: default avatarZhang Rui <rui.zhang@intel.com>
Signed-off-by: default avatarLen Brown <len.brown@intel.com>
parent f51e8391
...@@ -1462,12 +1462,14 @@ acpi_video_bus_get_one_device(struct acpi_device *device, ...@@ -1462,12 +1462,14 @@ acpi_video_bus_get_one_device(struct acpi_device *device,
static void acpi_video_device_rebind(struct acpi_video_bus *video) static void acpi_video_device_rebind(struct acpi_video_bus *video)
{ {
struct list_head *node, *next; struct acpi_video_device *dev;
list_for_each_safe(node, next, &video->video_device_list) {
struct acpi_video_device *dev = down(&video->sem);
container_of(node, struct acpi_video_device, entry);
list_for_each_entry(dev, &video->video_device_list, entry)
acpi_video_device_bind(video, dev); acpi_video_device_bind(video, dev);
}
up(&video->sem);
} }
/* /*
...@@ -1592,30 +1594,33 @@ static int acpi_video_device_enumerate(struct acpi_video_bus *video) ...@@ -1592,30 +1594,33 @@ static int acpi_video_device_enumerate(struct acpi_video_bus *video)
static int acpi_video_switch_output(struct acpi_video_bus *video, int event) static int acpi_video_switch_output(struct acpi_video_bus *video, int event)
{ {
struct list_head *node, *next; struct list_head *node;
struct acpi_video_device *dev = NULL; struct acpi_video_device *dev = NULL;
struct acpi_video_device *dev_next = NULL; struct acpi_video_device *dev_next = NULL;
struct acpi_video_device *dev_prev = NULL; struct acpi_video_device *dev_prev = NULL;
unsigned long state; unsigned long state;
int status = 0; int status = 0;
down(&video->sem);
list_for_each_safe(node, next, &video->video_device_list) { list_for_each(node, &video->video_device_list) {
dev = container_of(node, struct acpi_video_device, entry); dev = container_of(node, struct acpi_video_device, entry);
status = acpi_video_device_get_state(dev, &state); status = acpi_video_device_get_state(dev, &state);
if (state & 0x2) { if (state & 0x2) {
dev_next = dev_next = container_of(node->next,
container_of(node->next, struct acpi_video_device, struct acpi_video_device, entry);
entry); dev_prev = container_of(node->prev,
dev_prev = struct acpi_video_device, entry);
container_of(node->prev, struct acpi_video_device,
entry);
goto out; goto out;
} }
} }
dev_next = container_of(node->next, struct acpi_video_device, entry); dev_next = container_of(node->next, struct acpi_video_device, entry);
dev_prev = container_of(node->prev, struct acpi_video_device, entry); dev_prev = container_of(node->prev, struct acpi_video_device, entry);
out: out:
up(&video->sem);
switch (event) { switch (event) {
case ACPI_VIDEO_NOTIFY_CYCLE: case ACPI_VIDEO_NOTIFY_CYCLE:
case ACPI_VIDEO_NOTIFY_NEXT_OUTPUT: case ACPI_VIDEO_NOTIFY_NEXT_OUTPUT:
...@@ -1691,24 +1696,17 @@ acpi_video_bus_get_devices(struct acpi_video_bus *video, ...@@ -1691,24 +1696,17 @@ acpi_video_bus_get_devices(struct acpi_video_bus *video,
struct acpi_device *device) struct acpi_device *device)
{ {
int status = 0; int status = 0;
struct list_head *node, *next; struct acpi_device *dev;
acpi_video_device_enumerate(video); acpi_video_device_enumerate(video);
list_for_each_safe(node, next, &device->children) { list_for_each_entry(dev, &device->children, node) {
struct acpi_device *dev =
list_entry(node, struct acpi_device, node);
if (!dev)
continue;
status = acpi_video_bus_get_one_device(dev, video); status = acpi_video_bus_get_one_device(dev, video);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
ACPI_EXCEPTION((AE_INFO, status, "Cant attach device")); ACPI_EXCEPTION((AE_INFO, status, "Cant attach device"));
continue; continue;
} }
} }
return status; return status;
} }
...@@ -1724,9 +1722,6 @@ static int acpi_video_bus_put_one_device(struct acpi_video_device *device) ...@@ -1724,9 +1722,6 @@ static int acpi_video_bus_put_one_device(struct acpi_video_device *device)
video = device->video; video = device->video;
down(&video->sem);
list_del(&device->entry);
up(&video->sem);
acpi_video_device_remove_fs(device->dev); acpi_video_device_remove_fs(device->dev);
status = acpi_remove_notify_handler(device->dev->handle, status = acpi_remove_notify_handler(device->dev->handle,
...@@ -1734,31 +1729,33 @@ static int acpi_video_bus_put_one_device(struct acpi_video_device *device) ...@@ -1734,31 +1729,33 @@ static int acpi_video_bus_put_one_device(struct acpi_video_device *device)
acpi_video_device_notify); acpi_video_device_notify);
backlight_device_unregister(device->backlight); backlight_device_unregister(device->backlight);
video_output_unregister(device->output_dev); video_output_unregister(device->output_dev);
return 0; return 0;
} }
static int acpi_video_bus_put_devices(struct acpi_video_bus *video) static int acpi_video_bus_put_devices(struct acpi_video_bus *video)
{ {
int status; int status;
struct list_head *node, *next; struct acpi_video_device *dev, *next;
down(&video->sem);
list_for_each_safe(node, next, &video->video_device_list) { list_for_each_entry_safe(dev, next, &video->video_device_list, entry) {
struct acpi_video_device *data =
list_entry(node, struct acpi_video_device, entry);
if (!data)
continue;
status = acpi_video_bus_put_one_device(data); status = acpi_video_bus_put_one_device(dev);
if (ACPI_FAILURE(status)) if (ACPI_FAILURE(status))
printk(KERN_WARNING PREFIX printk(KERN_WARNING PREFIX
"hhuuhhuu bug in acpi video driver.\n"); "hhuuhhuu bug in acpi video driver.\n");
if (data->brightness) if (dev->brightness) {
kfree(data->brightness->levels); kfree(dev->brightness->levels);
kfree(data->brightness); kfree(dev->brightness);
kfree(data);
} }
list_del(&dev->entry);
kfree(dev);
}
up(&video->sem);
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment