driver core: class: properly reference count class_dev_iter()
Subsystems (2)
Greg Kroah-Hartman
maintainerPATCH 1/1 driver core: class: properly reference count class_dev_iter()
When class_dev_iter is initialized, the reference count for the subsys private structure is incremented, but never decremented, causing a memory leak over time. To resolve this, save off a pointer to the internal structure into the class_dev_iter structure and then when the iterator is finished, drop the reference count.
--- drivers/base/class.c | 2 ++ include/linux/device/class.h | 1 + 2 files changed, 3 insertions(+)
drivers/base/class.c +2 -0
@@ -320,6 +320,7 @@ void class_dev_iter_init(struct class_dev_iter *iter, const struct class *class, start_knode = &start->p->knode_class;klist_iter_init_node (&sp->klist_devices, &iter->ki, start_knode); iter->type = type; + iter->sp = sp; }EXPORT_SYMBOL_GPL (class_dev_iter_init);
@@ -361,6 +362,7 @@ EXPORT_SYMBOL_GPL(class_dev_iter_next);void class_dev_iter_exit (struct class_dev_iter *iter) {klist_iter_exit (&iter->ki); +subsys_put (iter->sp); }EXPORT_SYMBOL_GPL (class_dev_iter_exit);
include/linux/device/class.h +1 -0
@@ -74,6 +74,7 @@ struct class {struct class_dev_iter {struct klist_iter ki;const struct device_type *type; +struct subsys_private *sp; };int __must_check class_register (const struct class *class);
Signature · 1 line
2.40.1
Quoted 7 lines · Greg Kroah-Hartman
When
class_dev_iteris initialized, the reference count for the subsys private structure is incremented, but never decremented, causing a memory leak over time. To resolve this, save off a pointer to the internal structure into theclass_dev_iterstructure and then when the iterator is finished, drop the reference count.
Quoted 5 lines
Reported-and-tested-by [email protected]Reported-by Mirsad Goran Todorovac <[email protected]>Cc "Rafael J. Wysocki" <[email protected]>Cc Alan Stern <[email protected]>Signed-off-by Greg Kroah-Hartman <[email protected]>
Quoted 40 lines
--- drivers/base/class.c | 2 ++ include/linux/device/class.h | 1 + 2 files changed, 3 insertions(+)drivers/base/class.c +2
-0@@ -320,6 +320,7 @@ void class_dev_iter_init(struct class_dev_iter *iter, const struct class *class, start_knode = &start->p->knode_class;klist_iter_init_node (&sp->klist_devices, &iter->ki, start_knode); iter->type = type; + iter->sp = sp; }EXPORT_SYMBOL_GPL (class_dev_iter_init);@@ -361,6 +362,7 @@ EXPORT_SYMBOL_GPL(class_dev_iter_next);void class_dev_iter_exit (struct class_dev_iter *iter) {klist_iter_exit (&iter->ki); +subsys_put (iter->sp); }EXPORT_SYMBOL_GPL (class_dev_iter_exit);include/linux/device/class.h +1
-1@@ -74,6 +74,7 @@ struct class {struct class_dev_iter {struct klist_iter ki;const struct device_type *type; +struct subsys_private *sp; };int __must_check class_register (const struct class *class); --2.40.1
Quoted 11 lines · Greg Kroah-Hartman
When
class_dev_iteris initialized, the reference count for the subsys private structure is incremented, but never decremented, causing a memory leak over time. To resolve this, save off a pointer to the internal structure into theclass_dev_iterstructure and then when the iterator is finished, drop the reference count.Reported-and-tested-by [email protected]Reported-by Mirsad Goran Todorovac <[email protected]>Cc "Rafael J. Wysocki" <[email protected]>Cc Alan Stern <[email protected]>Signed-off-by Greg Kroah-Hartman <[email protected]>
Hi, Greg,
Did I forget to give the
I apologise if I did.
Best regards,
Mirsad
Quoted 37 lines
--- drivers/base/class.c | 2 ++ include/linux/device/class.h | 1 + 2 files changed, 3 insertions(+)drivers/base/class.c +2
-0@@ -320,6 +320,7 @@ void class_dev_iter_init(struct class_dev_iter *iter, const struct class *class, start_knode = &start->p->knode_class;klist_iter_init_node (&sp->klist_devices, &iter->ki, start_knode); iter->type = type; + iter->sp = sp; }EXPORT_SYMBOL_GPL (class_dev_iter_init);@@ -361,6 +362,7 @@ EXPORT_SYMBOL_GPL(class_dev_iter_next);void class_dev_iter_exit (struct class_dev_iter *iter) {klist_iter_exit (&iter->ki); +subsys_put (iter->sp); }EXPORT_SYMBOL_GPL (class_dev_iter_exit);include/linux/device/class.h +1
-0@@ -74,6 +74,7 @@ struct class {struct class_dev_iter {struct klist_iter ki;const struct device_type *type; +struct subsys_private *sp; };int __must_check class_register (const struct class *class);