On Thu, May 15, 2025 at 11:23 AM Pasha Tatashin <pasha.tatashin@xxxxxxxxxx> wrote: > > +int liveupdate_register_subsystem(struct liveupdate_subsystem *h) > +{ > + struct liveupdate_subsystem *iter; > + int ret = 0; > + > + luo_state_read_enter(); > + if (!liveupdate_state_normal() && !liveupdate_state_updated()) { > + luo_state_read_exit(); > + return -EBUSY; > + } > + > + mutex_lock(&luo_subsystem_list_mutex); > + list_for_each_entry(iter, &luo_subsystems_list, list) { > + if (iter == h) { > + pr_warn("Subsystem '%s' (%p) already registered.\n", > + h->name, h); > + ret = -EEXIST; > + goto out_unlock; > + } > + > + if (!strcmp(iter->name, h->name)) { > + pr_err("Subsystem with name '%s' already registered.\n", > + h->name); > + ret = -EEXIST; > + goto out_unlock; > + } > + } > + > + INIT_LIST_HEAD(&h->list); > + list_add_tail(&h->list, &luo_subsystems_list); > + > +out_unlock: > + mutex_unlock(&luo_subsystem_list_mutex); > + luo_state_read_exit(); > + > + return ret; > +} Suggest using guard()() and scoped_guard() throughout this series instead of manual lock/unlock and up/down. That will simplify the code and reduce the chance of silly bugs where a code path misses an unlock/down.