Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ALSA: core: Use guard() for locking

We can simplify the code gracefully with new guard() macro and co for
automatic cleanup of locks.

Only the code refactoring, and no functional changes.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20240227085306.9764-12-tiwai@suse.de

+107 -137
+91 -108
sound/core/init.c
··· 284 284 if (xid) 285 285 strscpy(card->id, xid, sizeof(card->id)); 286 286 err = 0; 287 - mutex_lock(&snd_card_mutex); 288 - if (idx < 0) /* first check the matching module-name slot */ 289 - idx = get_slot_from_bitmask(idx, module_slot_match, module); 290 - if (idx < 0) /* if not matched, assign an empty slot */ 291 - idx = get_slot_from_bitmask(idx, check_empty_slot, module); 292 - if (idx < 0) 293 - err = -ENODEV; 294 - else if (idx < snd_ecards_limit) { 295 - if (test_bit(idx, snd_cards_lock)) 296 - err = -EBUSY; /* invalid */ 297 - } else if (idx >= SNDRV_CARDS) 298 - err = -ENODEV; 287 + scoped_guard(mutex, &snd_card_mutex) { 288 + if (idx < 0) /* first check the matching module-name slot */ 289 + idx = get_slot_from_bitmask(idx, module_slot_match, module); 290 + if (idx < 0) /* if not matched, assign an empty slot */ 291 + idx = get_slot_from_bitmask(idx, check_empty_slot, module); 292 + if (idx < 0) 293 + err = -ENODEV; 294 + else if (idx < snd_ecards_limit) { 295 + if (test_bit(idx, snd_cards_lock)) 296 + err = -EBUSY; /* invalid */ 297 + } else if (idx >= SNDRV_CARDS) 298 + err = -ENODEV; 299 + if (!err) { 300 + set_bit(idx, snd_cards_lock); /* lock it */ 301 + if (idx >= snd_ecards_limit) 302 + snd_ecards_limit = idx + 1; /* increase the limit */ 303 + } 304 + } 299 305 if (err < 0) { 300 - mutex_unlock(&snd_card_mutex); 301 306 dev_err(parent, "cannot find the slot for index %d (range 0-%i), error: %d\n", 302 - idx, snd_ecards_limit - 1, err); 307 + idx, snd_ecards_limit - 1, err); 303 308 if (!card->managed) 304 309 kfree(card); /* manually free here, as no destructor called */ 305 310 return err; 306 311 } 307 - set_bit(idx, snd_cards_lock); /* lock it */ 308 - if (idx >= snd_ecards_limit) 309 - snd_ecards_limit = idx + 1; /* increase the limit */ 310 - mutex_unlock(&snd_card_mutex); 311 312 card->dev = parent; 312 313 card->number = idx; 313 314 #ifdef MODULE ··· 387 386 { 388 387 struct snd_card *card; 389 388 390 - mutex_lock(&snd_card_mutex); 389 + guard(mutex)(&snd_card_mutex); 391 390 card = snd_cards[idx]; 392 391 if (card) 393 392 get_device(&card->card_dev); 394 - mutex_unlock(&snd_card_mutex); 395 393 return card; 396 394 } 397 395 EXPORT_SYMBOL_GPL(snd_card_ref); ··· 398 398 /* return non-zero if a card is already locked */ 399 399 int snd_card_locked(int card) 400 400 { 401 - int locked; 402 - 403 - mutex_lock(&snd_card_mutex); 404 - locked = test_bit(card, snd_cards_lock); 405 - mutex_unlock(&snd_card_mutex); 406 - return locked; 401 + guard(mutex)(&snd_card_mutex); 402 + return test_bit(card, snd_cards_lock); 407 403 } 408 404 409 405 static loff_t snd_disconnect_llseek(struct file *file, loff_t offset, int orig) ··· 423 427 { 424 428 struct snd_monitor_file *df = NULL, *_df; 425 429 426 - spin_lock(&shutdown_lock); 427 - list_for_each_entry(_df, &shutdown_files, shutdown_list) { 428 - if (_df->file == file) { 429 - df = _df; 430 - list_del_init(&df->shutdown_list); 431 - break; 430 + scoped_guard(spinlock, &shutdown_lock) { 431 + list_for_each_entry(_df, &shutdown_files, shutdown_list) { 432 + if (_df->file == file) { 433 + df = _df; 434 + list_del_init(&df->shutdown_list); 435 + break; 436 + } 432 437 } 433 438 } 434 - spin_unlock(&shutdown_lock); 435 439 436 440 if (likely(df)) { 437 441 if ((file->f_flags & FASYNC) && df->disconnected_f_op->fasync) ··· 497 501 if (!card) 498 502 return; 499 503 500 - spin_lock(&card->files_lock); 501 - if (card->shutdown) { 502 - spin_unlock(&card->files_lock); 503 - return; 504 + scoped_guard(spinlock, &card->files_lock) { 505 + if (card->shutdown) 506 + return; 507 + card->shutdown = 1; 508 + 509 + /* replace file->f_op with special dummy operations */ 510 + list_for_each_entry(mfile, &card->files_list, list) { 511 + /* it's critical part, use endless loop */ 512 + /* we have no room to fail */ 513 + mfile->disconnected_f_op = mfile->file->f_op; 514 + 515 + scoped_guard(spinlock, &shutdown_lock) 516 + list_add(&mfile->shutdown_list, &shutdown_files); 517 + 518 + mfile->file->f_op = &snd_shutdown_f_ops; 519 + fops_get(mfile->file->f_op); 520 + } 504 521 } 505 - card->shutdown = 1; 506 - 507 - /* replace file->f_op with special dummy operations */ 508 - list_for_each_entry(mfile, &card->files_list, list) { 509 - /* it's critical part, use endless loop */ 510 - /* we have no room to fail */ 511 - mfile->disconnected_f_op = mfile->file->f_op; 512 - 513 - spin_lock(&shutdown_lock); 514 - list_add(&mfile->shutdown_list, &shutdown_files); 515 - spin_unlock(&shutdown_lock); 516 - 517 - mfile->file->f_op = &snd_shutdown_f_ops; 518 - fops_get(mfile->file->f_op); 519 - } 520 - spin_unlock(&card->files_lock); 521 522 522 523 /* notify all connected devices about disconnection */ 523 524 /* at this point, they cannot respond to any calls except release() */ ··· 537 544 } 538 545 539 546 /* disable fops (user space) operations for ALSA API */ 540 - mutex_lock(&snd_card_mutex); 541 - snd_cards[card->number] = NULL; 542 - clear_bit(card->number, snd_cards_lock); 543 - mutex_unlock(&snd_card_mutex); 547 + scoped_guard(mutex, &snd_card_mutex) { 548 + snd_cards[card->number] = NULL; 549 + clear_bit(card->number, snd_cards_lock); 550 + } 544 551 545 552 #ifdef CONFIG_PM 546 553 wake_up(&card->power_sleep); ··· 562 569 { 563 570 snd_card_disconnect(card); 564 571 565 - spin_lock_irq(&card->files_lock); 572 + guard(spinlock_irq)(&card->files_lock); 566 573 wait_event_lock_irq(card->remove_sleep, 567 574 list_empty(&card->files_list), 568 575 card->files_lock); 569 - spin_unlock_irq(&card->files_lock); 570 576 } 571 577 EXPORT_SYMBOL_GPL(snd_card_disconnect_sync); 572 578 ··· 759 767 /* check if user specified own card->id */ 760 768 if (card->id[0] != '\0') 761 769 return; 762 - mutex_lock(&snd_card_mutex); 770 + guard(mutex)(&snd_card_mutex); 763 771 snd_card_set_id_no_lock(card, nid, nid); 764 - mutex_unlock(&snd_card_mutex); 765 772 } 766 773 EXPORT_SYMBOL(snd_card_set_id); 767 774 ··· 788 797 } 789 798 memcpy(buf1, buf, copy); 790 799 buf1[copy] = '\0'; 791 - mutex_lock(&snd_card_mutex); 792 - if (!card_id_ok(NULL, buf1)) { 793 - mutex_unlock(&snd_card_mutex); 800 + guard(mutex)(&snd_card_mutex); 801 + if (!card_id_ok(NULL, buf1)) 794 802 return -EEXIST; 795 - } 796 803 strcpy(card->id, buf1); 797 804 snd_info_card_id_change(card); 798 - mutex_unlock(&snd_card_mutex); 799 805 800 806 return count; 801 807 } ··· 885 897 err = snd_device_register_all(card); 886 898 if (err < 0) 887 899 return err; 888 - mutex_lock(&snd_card_mutex); 889 - if (snd_cards[card->number]) { 890 - /* already registered */ 891 - mutex_unlock(&snd_card_mutex); 892 - return snd_info_card_register(card); /* register pending info */ 900 + scoped_guard(mutex, &snd_card_mutex) { 901 + if (snd_cards[card->number]) { 902 + /* already registered */ 903 + return snd_info_card_register(card); /* register pending info */ 904 + } 905 + if (*card->id) { 906 + /* make a unique id name from the given string */ 907 + char tmpid[sizeof(card->id)]; 908 + 909 + memcpy(tmpid, card->id, sizeof(card->id)); 910 + snd_card_set_id_no_lock(card, tmpid, tmpid); 911 + } else { 912 + /* create an id from either shortname or longname */ 913 + const char *src; 914 + 915 + src = *card->shortname ? card->shortname : card->longname; 916 + snd_card_set_id_no_lock(card, src, 917 + retrieve_id_from_card_name(src)); 918 + } 919 + snd_cards[card->number] = card; 893 920 } 894 - if (*card->id) { 895 - /* make a unique id name from the given string */ 896 - char tmpid[sizeof(card->id)]; 897 - memcpy(tmpid, card->id, sizeof(card->id)); 898 - snd_card_set_id_no_lock(card, tmpid, tmpid); 899 - } else { 900 - /* create an id from either shortname or longname */ 901 - const char *src; 902 - src = *card->shortname ? card->shortname : card->longname; 903 - snd_card_set_id_no_lock(card, src, 904 - retrieve_id_from_card_name(src)); 905 - } 906 - snd_cards[card->number] = card; 907 - mutex_unlock(&snd_card_mutex); 908 921 err = snd_info_card_register(card); 909 922 if (err < 0) 910 923 return err; ··· 926 937 struct snd_card *card; 927 938 928 939 for (idx = count = 0; idx < SNDRV_CARDS; idx++) { 929 - mutex_lock(&snd_card_mutex); 940 + guard(mutex)(&snd_card_mutex); 930 941 card = snd_cards[idx]; 931 942 if (card) { 932 943 count++; ··· 938 949 snd_iprintf(buffer, " %s\n", 939 950 card->longname); 940 951 } 941 - mutex_unlock(&snd_card_mutex); 942 952 } 943 953 if (!count) 944 954 snd_iprintf(buffer, "--- no soundcards ---\n"); ··· 950 962 struct snd_card *card; 951 963 952 964 for (idx = count = 0; idx < SNDRV_CARDS; idx++) { 953 - mutex_lock(&snd_card_mutex); 965 + guard(mutex)(&snd_card_mutex); 954 966 card = snd_cards[idx]; 955 967 if (card) { 956 968 count++; 957 969 snd_iprintf(buffer, "%s\n", card->longname); 958 970 } 959 - mutex_unlock(&snd_card_mutex); 960 971 } 961 972 if (!count) { 962 973 snd_iprintf(buffer, "--- no soundcards ---\n"); ··· 972 985 struct snd_card *card; 973 986 974 987 for (idx = 0; idx < SNDRV_CARDS; idx++) { 975 - mutex_lock(&snd_card_mutex); 988 + guard(mutex)(&snd_card_mutex); 976 989 card = snd_cards[idx]; 977 990 if (card) 978 991 snd_iprintf(buffer, "%2i %s\n", 979 992 idx, card->module->name); 980 - mutex_unlock(&snd_card_mutex); 981 993 } 982 994 } 983 995 #endif ··· 1058 1072 mfile->file = file; 1059 1073 mfile->disconnected_f_op = NULL; 1060 1074 INIT_LIST_HEAD(&mfile->shutdown_list); 1061 - spin_lock(&card->files_lock); 1075 + guard(spinlock)(&card->files_lock); 1062 1076 if (card->shutdown) { 1063 - spin_unlock(&card->files_lock); 1064 1077 kfree(mfile); 1065 1078 return -ENODEV; 1066 1079 } 1067 1080 list_add(&mfile->list, &card->files_list); 1068 1081 get_device(&card->card_dev); 1069 - spin_unlock(&card->files_lock); 1070 1082 return 0; 1071 1083 } 1072 1084 EXPORT_SYMBOL(snd_card_file_add); ··· 1086 1102 { 1087 1103 struct snd_monitor_file *mfile, *found = NULL; 1088 1104 1089 - spin_lock(&card->files_lock); 1090 - list_for_each_entry(mfile, &card->files_list, list) { 1091 - if (mfile->file == file) { 1092 - list_del(&mfile->list); 1093 - spin_lock(&shutdown_lock); 1094 - list_del(&mfile->shutdown_list); 1095 - spin_unlock(&shutdown_lock); 1096 - if (mfile->disconnected_f_op) 1097 - fops_put(mfile->disconnected_f_op); 1098 - found = mfile; 1099 - break; 1105 + scoped_guard(spinlock, &card->files_lock) { 1106 + list_for_each_entry(mfile, &card->files_list, list) { 1107 + if (mfile->file == file) { 1108 + list_del(&mfile->list); 1109 + scoped_guard(spinlock, &shutdown_lock) 1110 + list_del(&mfile->shutdown_list); 1111 + if (mfile->disconnected_f_op) 1112 + fops_put(mfile->disconnected_f_op); 1113 + found = mfile; 1114 + break; 1115 + } 1100 1116 } 1117 + if (list_empty(&card->files_list)) 1118 + wake_up_all(&card->remove_sleep); 1101 1119 } 1102 - if (list_empty(&card->files_list)) 1103 - wake_up_all(&card->remove_sleep); 1104 - spin_unlock(&card->files_lock); 1105 1120 if (!found) { 1106 1121 dev_err(card->dev, "card file remove problem (%p)\n", file); 1107 1122 return -ENOENT;
+11 -17
sound/core/sound.c
··· 103 103 104 104 if (minor >= ARRAY_SIZE(snd_minors)) 105 105 return NULL; 106 - mutex_lock(&sound_mutex); 106 + guard(mutex)(&sound_mutex); 107 107 mreg = snd_minors[minor]; 108 108 if (mreg && mreg->type == type) { 109 109 private_data = mreg->private_data; ··· 111 111 get_device(&mreg->card_ptr->card_dev); 112 112 } else 113 113 private_data = NULL; 114 - mutex_unlock(&sound_mutex); 115 114 return private_data; 116 115 } 117 116 EXPORT_SYMBOL(snd_lookup_minor_data); ··· 149 150 150 151 if (minor >= ARRAY_SIZE(snd_minors)) 151 152 return -ENODEV; 152 - mutex_lock(&sound_mutex); 153 - mptr = snd_minors[minor]; 154 - if (mptr == NULL) { 155 - mptr = autoload_device(minor); 156 - if (!mptr) { 157 - mutex_unlock(&sound_mutex); 158 - return -ENODEV; 153 + scoped_guard(mutex, &sound_mutex) { 154 + mptr = snd_minors[minor]; 155 + if (mptr == NULL) { 156 + mptr = autoload_device(minor); 157 + if (!mptr) 158 + return -ENODEV; 159 159 } 160 + new_fops = fops_get(mptr->f_ops); 160 161 } 161 - new_fops = fops_get(mptr->f_ops); 162 - mutex_unlock(&sound_mutex); 163 162 if (!new_fops) 164 163 return -ENODEV; 165 164 replace_fops(file, new_fops); ··· 266 269 preg->f_ops = f_ops; 267 270 preg->private_data = private_data; 268 271 preg->card_ptr = card; 269 - mutex_lock(&sound_mutex); 272 + guard(mutex)(&sound_mutex); 270 273 minor = snd_find_free_minor(type, card, dev); 271 274 if (minor < 0) { 272 275 err = minor; ··· 281 284 282 285 snd_minors[minor] = preg; 283 286 error: 284 - mutex_unlock(&sound_mutex); 285 287 if (err < 0) 286 288 kfree(preg); 287 289 return err; ··· 301 305 int minor; 302 306 struct snd_minor *preg; 303 307 304 - mutex_lock(&sound_mutex); 308 + guard(mutex)(&sound_mutex); 305 309 for (minor = 0; minor < ARRAY_SIZE(snd_minors); ++minor) { 306 310 preg = snd_minors[minor]; 307 311 if (preg && preg->dev == dev) { ··· 311 315 break; 312 316 } 313 317 } 314 - mutex_unlock(&sound_mutex); 315 318 if (minor >= ARRAY_SIZE(snd_minors)) 316 319 return -ENOENT; 317 320 return 0; ··· 350 355 int minor; 351 356 struct snd_minor *mptr; 352 357 353 - mutex_lock(&sound_mutex); 358 + guard(mutex)(&sound_mutex); 354 359 for (minor = 0; minor < SNDRV_OS_MINORS; ++minor) { 355 360 mptr = snd_minors[minor]; 356 361 if (!mptr) ··· 368 373 snd_iprintf(buffer, "%3i: : %s\n", minor, 369 374 snd_device_type_name(mptr->type)); 370 375 } 371 - mutex_unlock(&sound_mutex); 372 376 } 373 377 374 378 int __init snd_minor_info_init(void)
+5 -12
sound/core/sound_oss.c
··· 29 29 30 30 if (minor >= ARRAY_SIZE(snd_oss_minors)) 31 31 return NULL; 32 - mutex_lock(&sound_oss_mutex); 32 + guard(mutex)(&sound_oss_mutex); 33 33 mreg = snd_oss_minors[minor]; 34 34 if (mreg && mreg->type == type) { 35 35 private_data = mreg->private_data; ··· 37 37 get_device(&mreg->card_ptr->card_dev); 38 38 } else 39 39 private_data = NULL; 40 - mutex_unlock(&sound_oss_mutex); 41 40 return private_data; 42 41 } 43 42 EXPORT_SYMBOL(snd_lookup_oss_minor_data); ··· 105 106 preg->f_ops = f_ops; 106 107 preg->private_data = private_data; 107 108 preg->card_ptr = card; 108 - mutex_lock(&sound_oss_mutex); 109 + guard(mutex)(&sound_oss_mutex); 109 110 snd_oss_minors[minor] = preg; 110 111 minor_unit = SNDRV_MINOR_OSS_DEVICE(minor); 111 112 switch (minor_unit) { ··· 129 130 goto __end; 130 131 snd_oss_minors[track2] = preg; 131 132 } 132 - mutex_unlock(&sound_oss_mutex); 133 133 return 0; 134 134 135 135 __end: ··· 137 139 if (register1 >= 0) 138 140 unregister_sound_special(register1); 139 141 snd_oss_minors[minor] = NULL; 140 - mutex_unlock(&sound_oss_mutex); 141 142 kfree(preg); 142 143 return -EBUSY; 143 144 } ··· 153 156 return 0; 154 157 if (minor < 0) 155 158 return minor; 156 - mutex_lock(&sound_oss_mutex); 159 + guard(mutex)(&sound_oss_mutex); 157 160 mptr = snd_oss_minors[minor]; 158 - if (mptr == NULL) { 159 - mutex_unlock(&sound_oss_mutex); 161 + if (mptr == NULL) 160 162 return -ENOENT; 161 - } 162 163 switch (SNDRV_MINOR_OSS_DEVICE(minor)) { 163 164 case SNDRV_MINOR_OSS_PCM: 164 165 track2 = SNDRV_MINOR_OSS(cidx, SNDRV_MINOR_OSS_AUDIO); ··· 171 176 if (track2 >= 0) 172 177 snd_oss_minors[track2] = NULL; 173 178 snd_oss_minors[minor] = NULL; 174 - mutex_unlock(&sound_oss_mutex); 175 179 176 180 /* call unregister_sound_special() outside sound_oss_mutex; 177 181 * otherwise may deadlock, as it can trigger the release of a card ··· 214 220 int minor; 215 221 struct snd_minor *mptr; 216 222 217 - mutex_lock(&sound_oss_mutex); 223 + guard(mutex)(&sound_oss_mutex); 218 224 for (minor = 0; minor < SNDRV_OSS_MINORS; ++minor) { 219 225 mptr = snd_oss_minors[minor]; 220 226 if (!mptr) ··· 227 233 snd_iprintf(buffer, "%3i: : %s\n", minor, 228 234 snd_oss_device_type_name(mptr->type)); 229 235 } 230 - mutex_unlock(&sound_oss_mutex); 231 236 } 232 237 233 238