Skip to content

Commit 7dba48a

Browse files
committed
ALSA: control_led: Use guard() for locking
We can simplify the code gracefully with new guard() macro and co for automatic cleanup of locks. A couple of functions that use snd_card_ref() and *_unref() are also cleaned up with a defined class, too. Only the code refactoring, and no functional changes. Signed-off-by: Takashi Iwai <tiwai@suse.de> Link: https://lore.kernel.org/r/20240227085306.9764-25-tiwai@suse.de
1 parent 3923de0 commit 7dba48a

1 file changed

Lines changed: 65 additions & 85 deletions

File tree

sound/core/control_led.c

Lines changed: 65 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -147,29 +147,27 @@ static void snd_ctl_led_set_state(struct snd_card *card, unsigned int access,
147147
return;
148148
route = -1;
149149
found = false;
150-
mutex_lock(&snd_ctl_led_mutex);
151-
/* the card may not be registered (active) at this point */
152-
if (card && !snd_ctl_led_card_valid[card->number]) {
153-
mutex_unlock(&snd_ctl_led_mutex);
154-
return;
155-
}
156-
list_for_each_entry(lctl, &led->controls, list) {
157-
if (lctl->kctl == kctl && lctl->index_offset == ioff)
158-
found = true;
159-
UPDATE_ROUTE(route, snd_ctl_led_get(lctl));
160-
}
161-
if (!found && kctl && card) {
162-
lctl = kzalloc(sizeof(*lctl), GFP_KERNEL);
163-
if (lctl) {
164-
lctl->card = card;
165-
lctl->access = access;
166-
lctl->kctl = kctl;
167-
lctl->index_offset = ioff;
168-
list_add(&lctl->list, &led->controls);
150+
scoped_guard(mutex, &snd_ctl_led_mutex) {
151+
/* the card may not be registered (active) at this point */
152+
if (card && !snd_ctl_led_card_valid[card->number])
153+
return;
154+
list_for_each_entry(lctl, &led->controls, list) {
155+
if (lctl->kctl == kctl && lctl->index_offset == ioff)
156+
found = true;
169157
UPDATE_ROUTE(route, snd_ctl_led_get(lctl));
170158
}
159+
if (!found && kctl && card) {
160+
lctl = kzalloc(sizeof(*lctl), GFP_KERNEL);
161+
if (lctl) {
162+
lctl->card = card;
163+
lctl->access = access;
164+
lctl->kctl = kctl;
165+
lctl->index_offset = ioff;
166+
list_add(&lctl->list, &led->controls);
167+
UPDATE_ROUTE(route, snd_ctl_led_get(lctl));
168+
}
169+
}
171170
}
172-
mutex_unlock(&snd_ctl_led_mutex);
173171
switch (led->mode) {
174172
case MODE_OFF: route = 1; break;
175173
case MODE_ON: route = 0; break;
@@ -201,14 +199,13 @@ static unsigned int snd_ctl_led_remove(struct snd_kcontrol *kctl, unsigned int i
201199
struct snd_ctl_led_ctl *lctl;
202200
unsigned int ret = 0;
203201

204-
mutex_lock(&snd_ctl_led_mutex);
202+
guard(mutex)(&snd_ctl_led_mutex);
205203
lctl = snd_ctl_led_find(kctl, ioff);
206204
if (lctl && (access == 0 || access != lctl->access)) {
207205
ret = lctl->access;
208206
list_del(&lctl->list);
209207
kfree(lctl);
210208
}
211-
mutex_unlock(&snd_ctl_led_mutex);
212209
return ret;
213210
}
214211

@@ -239,44 +236,36 @@ static void snd_ctl_led_notify(struct snd_card *card, unsigned int mask,
239236
}
240237
}
241238

239+
DEFINE_FREE(snd_card_unref, struct snd_card *, if (_T) snd_card_unref(_T))
240+
242241
static int snd_ctl_led_set_id(int card_number, struct snd_ctl_elem_id *id,
243242
unsigned int group, bool set)
244243
{
245-
struct snd_card *card;
244+
struct snd_card *card __free(snd_card_unref) = NULL;
246245
struct snd_kcontrol *kctl;
247246
struct snd_kcontrol_volatile *vd;
248247
unsigned int ioff, access, new_access;
249-
int err = 0;
250248

251249
card = snd_card_ref(card_number);
252-
if (card) {
253-
down_write(&card->controls_rwsem);
254-
kctl = snd_ctl_find_id_locked(card, id);
255-
if (kctl) {
256-
ioff = snd_ctl_get_ioff(kctl, id);
257-
vd = &kctl->vd[ioff];
258-
access = vd->access & SNDRV_CTL_ELEM_ACCESS_LED_MASK;
259-
if (access != 0 && access != group_to_access(group)) {
260-
err = -EXDEV;
261-
goto unlock;
262-
}
263-
new_access = vd->access & ~SNDRV_CTL_ELEM_ACCESS_LED_MASK;
264-
if (set)
265-
new_access |= group_to_access(group);
266-
if (new_access != vd->access) {
267-
vd->access = new_access;
268-
snd_ctl_led_notify(card, SNDRV_CTL_EVENT_MASK_INFO, kctl, ioff);
269-
}
270-
} else {
271-
err = -ENOENT;
272-
}
273-
unlock:
274-
up_write(&card->controls_rwsem);
275-
snd_card_unref(card);
276-
} else {
277-
err = -ENXIO;
250+
if (!card)
251+
return -ENXIO;
252+
guard(rwsem_write)(&card->controls_rwsem);
253+
kctl = snd_ctl_find_id_locked(card, id);
254+
if (!kctl)
255+
return -ENOENT;
256+
ioff = snd_ctl_get_ioff(kctl, id);
257+
vd = &kctl->vd[ioff];
258+
access = vd->access & SNDRV_CTL_ELEM_ACCESS_LED_MASK;
259+
if (access != 0 && access != group_to_access(group))
260+
return -EXDEV;
261+
new_access = vd->access & ~SNDRV_CTL_ELEM_ACCESS_LED_MASK;
262+
if (set)
263+
new_access |= group_to_access(group);
264+
if (new_access != vd->access) {
265+
vd->access = new_access;
266+
snd_ctl_led_notify(card, SNDRV_CTL_EVENT_MASK_INFO, kctl, ioff);
278267
}
279-
return err;
268+
return 0;
280269
}
281270

282271
static void snd_ctl_led_refresh(void)
@@ -312,7 +301,7 @@ static void snd_ctl_led_clean(struct snd_card *card)
312301

313302
static int snd_ctl_led_reset(int card_number, unsigned int group)
314303
{
315-
struct snd_card *card;
304+
struct snd_card *card __free(snd_card_unref) = NULL;
316305
struct snd_ctl_led *led;
317306
struct snd_ctl_led_ctl *lctl;
318307
struct snd_kcontrol_volatile *vd;
@@ -322,26 +311,22 @@ static int snd_ctl_led_reset(int card_number, unsigned int group)
322311
if (!card)
323312
return -ENXIO;
324313

325-
mutex_lock(&snd_ctl_led_mutex);
326-
if (!snd_ctl_led_card_valid[card_number]) {
327-
mutex_unlock(&snd_ctl_led_mutex);
328-
snd_card_unref(card);
329-
return -ENXIO;
330-
}
331-
led = &snd_ctl_leds[group];
314+
scoped_guard(mutex, &snd_ctl_led_mutex) {
315+
if (!snd_ctl_led_card_valid[card_number])
316+
return -ENXIO;
317+
led = &snd_ctl_leds[group];
332318
repeat:
333-
list_for_each_entry(lctl, &led->controls, list)
334-
if (lctl->card == card) {
335-
vd = &lctl->kctl->vd[lctl->index_offset];
336-
vd->access &= ~group_to_access(group);
337-
snd_ctl_led_ctl_destroy(lctl);
338-
change = true;
339-
goto repeat;
340-
}
341-
mutex_unlock(&snd_ctl_led_mutex);
319+
list_for_each_entry(lctl, &led->controls, list)
320+
if (lctl->card == card) {
321+
vd = &lctl->kctl->vd[lctl->index_offset];
322+
vd->access &= ~group_to_access(group);
323+
snd_ctl_led_ctl_destroy(lctl);
324+
change = true;
325+
goto repeat;
326+
}
327+
}
342328
if (change)
343329
snd_ctl_led_set_state(NULL, group_to_access(group), NULL, 0);
344-
snd_card_unref(card);
345330
return 0;
346331
}
347332

@@ -353,9 +338,8 @@ static void snd_ctl_led_register(struct snd_card *card)
353338
if (snd_BUG_ON(card->number < 0 ||
354339
card->number >= ARRAY_SIZE(snd_ctl_led_card_valid)))
355340
return;
356-
mutex_lock(&snd_ctl_led_mutex);
357-
snd_ctl_led_card_valid[card->number] = true;
358-
mutex_unlock(&snd_ctl_led_mutex);
341+
scoped_guard(mutex, &snd_ctl_led_mutex)
342+
snd_ctl_led_card_valid[card->number] = true;
359343
/* the register callback is already called with held card->controls_rwsem */
360344
list_for_each_entry(kctl, &card->controls, list)
361345
for (ioff = 0; ioff < kctl->count; ioff++)
@@ -367,10 +351,10 @@ static void snd_ctl_led_register(struct snd_card *card)
367351
static void snd_ctl_led_disconnect(struct snd_card *card)
368352
{
369353
snd_ctl_led_sysfs_remove(card);
370-
mutex_lock(&snd_ctl_led_mutex);
371-
snd_ctl_led_card_valid[card->number] = false;
372-
snd_ctl_led_clean(card);
373-
mutex_unlock(&snd_ctl_led_mutex);
354+
scoped_guard(mutex, &snd_ctl_led_mutex) {
355+
snd_ctl_led_card_valid[card->number] = false;
356+
snd_ctl_led_clean(card);
357+
}
374358
snd_ctl_led_refresh();
375359
}
376360

@@ -430,9 +414,8 @@ static ssize_t mode_store(struct device *dev,
430414
else
431415
return count;
432416

433-
mutex_lock(&snd_ctl_led_mutex);
434-
led->mode = mode;
435-
mutex_unlock(&snd_ctl_led_mutex);
417+
scoped_guard(mutex, &snd_ctl_led_mutex)
418+
led->mode = mode;
436419

437420
snd_ctl_led_set_state(NULL, group_to_access(led->group), NULL, 0);
438421
return count;
@@ -615,15 +598,15 @@ static ssize_t list_show(struct device *dev,
615598
struct device_attribute *attr, char *buf)
616599
{
617600
struct snd_ctl_led_card *led_card = container_of(dev, struct snd_ctl_led_card, dev);
618-
struct snd_card *card;
601+
struct snd_card *card __free(snd_card_unref) = NULL;
619602
struct snd_ctl_led_ctl *lctl;
620603
size_t l = 0;
621604

622605
card = snd_card_ref(led_card->number);
623606
if (!card)
624607
return -ENXIO;
625-
down_read(&card->controls_rwsem);
626-
mutex_lock(&snd_ctl_led_mutex);
608+
guard(rwsem_read)(&card->controls_rwsem);
609+
guard(mutex)(&snd_ctl_led_mutex);
627610
if (snd_ctl_led_card_valid[led_card->number]) {
628611
list_for_each_entry(lctl, &led_card->led->controls, list) {
629612
if (lctl->card != card)
@@ -634,9 +617,6 @@ static ssize_t list_show(struct device *dev,
634617
lctl->kctl->id.numid + lctl->index_offset);
635618
}
636619
}
637-
mutex_unlock(&snd_ctl_led_mutex);
638-
up_read(&card->controls_rwsem);
639-
snd_card_unref(card);
640620
return l;
641621
}
642622

0 commit comments

Comments
 (0)