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.
Unified · Split
| @@ -320,6 +320,7 @@ void class_dev_iter_init(struct class_dev_iter *iter, const struct class *class, · 319 unmodified lines | |||
| 320 | start_knode = &start->p->knode_class; | 320 | start_knode = &start->p->knode_class; |
| 321 | klist_iter_init_node(&sp->klist_devices, &iter->ki, start_knode); | 321 | klist_iter_init_node(&sp->klist_devices, &iter->ki, start_knode); |
| 322 | iter->type = type; | 322 | iter->type = type; |
| 323 | iter->sp = sp; | ||
| 323 | } | 324 | } |
| 324 | EXPORT_SYMBOL_GPL(class_dev_iter_init); | 325 | EXPORT_SYMBOL_GPL(class_dev_iter_init); |
| 325 | 326 | ||
| @@ -361,6 +362,7 @@ EXPORT_SYMBOL_GPL(class_dev_iter_next); · 35 unmodified lines | |||
| 361 | void class_dev_iter_exit(struct class_dev_iter *iter) | 362 | void class_dev_iter_exit(struct class_dev_iter *iter) |
| 362 | { | 363 | { |
| 363 | klist_iter_exit(&iter->ki); | 364 | klist_iter_exit(&iter->ki); |
| 365 | subsys_put(iter->sp); | ||
| 364 | } | 366 | } |
| 365 | EXPORT_SYMBOL_GPL(class_dev_iter_exit); | 367 | EXPORT_SYMBOL_GPL(class_dev_iter_exit); |
| 366 | 368 | ||
| @@ -74,6 +74,7 @@ struct class { · 73 unmodified lines | |||
| 74 | struct class_dev_iter { | 74 | struct class_dev_iter { |
| 75 | struct klist_iter ki; | 75 | struct klist_iter ki; |
| 76 | const struct device_type *type; | 76 | const struct device_type *type; |
| 77 | struct subsys_private *sp; | ||
| 77 | }; | 78 | }; |
| 78 | 79 | ||
| 79 | int __must_check class_register(const struct class *class); | 80 | int __must_check class_register(const struct class *class); |