Подробности

[В начало]

Проблема в реализации № L0036

Краткое описание

gigaset: отсутствие вызовы module_put перед перезапуском if_open()

Подробное описание

Когда if_open() вызывает try_module_get(), а затем, после неудачной попытки захватить мьютекс, возвращает -ERESTARTSYS, она не вызывает module_put(). Вызов if_open() начинается снова, и внова захватывается модуль. Однако при закрытии файла устройства, if_close() вызывает module_put только один раз, и, в результате, модуль нельзя выгрузить.

Способы устранения

diff --git a/drivers/isdn/gigaset/interface.c b/drivers/isdn/gigaset/interface.c
index 59de638..e35058b 100644
--- a/drivers/isdn/gigaset/interface.c
+++ b/drivers/isdn/gigaset/interface.c
@@ -156,8 +156,10 @@ static int if_open(struct tty_struct *tty, struct file *filp)
 	if (!cs || !try_module_get(cs->driver->owner))
 		return -ENODEV;
 
-	if (mutex_lock_interruptible(&cs->mutex))
+	if (mutex_lock_interruptible(&cs->mutex)) {
+		module_put(cs->driver->owner);
 		return -ERESTARTSYS;
+	}
 	tty->driver_data = cs;
 
 	++cs->open_count;

Компонент

linux-kernel 2.6.39

Ссылки

https://lkml.org/lkml/2011/6/17/321

Принято

https://lkml.org/lkml/2011/6/17/321 commit 2f9381e

Статус

Исправлено в kernel 3.0-rc4

[В начало]