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

ALSA: timer: Use guard() for locking

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

For making changes easier, some functions widen the application of
register_mutex, but those shouldn't influence on any actual
performance.

Also, one code block was factored out as a function so that guard()
can be applied cleanly without much indentation.

There are still a few remaining explicit spin_lock/unlock calls, and
those are for the places where we do temporary unlock/relock, which
doesn't fit well with the guard(), so far.

Only the code refactoring, and no functional changes.

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

+177 -259
+175 -254
sound/core/timer.c
··· 224 224 return -EBUSY; 225 225 list_move_tail(&slave->open_list, &master->slave_list_head); 226 226 master->timer->num_instances++; 227 - spin_lock_irq(&slave_active_lock); 228 - spin_lock(&master->timer->lock); 227 + guard(spinlock_irq)(&slave_active_lock); 228 + guard(spinlock)(&master->timer->lock); 229 229 slave->master = master; 230 230 slave->timer = master->timer; 231 231 if (slave->flags & SNDRV_TIMER_IFLG_RUNNING) 232 232 list_add_tail(&slave->active_list, &master->slave_active_head); 233 - spin_unlock(&master->timer->lock); 234 - spin_unlock_irq(&slave_active_lock); 235 233 return 1; 236 234 } 237 235 ··· 380 382 } 381 383 EXPORT_SYMBOL(snd_timer_open); 382 384 385 + /* remove slave links, called from snd_timer_close_locked() below */ 386 + static void remove_slave_links(struct snd_timer_instance *timeri, 387 + struct snd_timer *timer) 388 + { 389 + struct snd_timer_instance *slave, *tmp; 390 + 391 + guard(spinlock_irq)(&slave_active_lock); 392 + guard(spinlock)(&timer->lock); 393 + timeri->timer = NULL; 394 + list_for_each_entry_safe(slave, tmp, &timeri->slave_list_head, open_list) { 395 + list_move_tail(&slave->open_list, &snd_timer_slave_list); 396 + timer->num_instances--; 397 + slave->master = NULL; 398 + slave->timer = NULL; 399 + list_del_init(&slave->ack_list); 400 + list_del_init(&slave->active_list); 401 + } 402 + } 403 + 383 404 /* 384 405 * close a timer instance 385 406 * call this with register_mutex down. ··· 407 390 struct device **card_devp_to_put) 408 391 { 409 392 struct snd_timer *timer = timeri->timer; 410 - struct snd_timer_instance *slave, *tmp; 411 393 412 394 if (timer) { 413 - spin_lock_irq(&timer->lock); 395 + guard(spinlock)(&timer->lock); 414 396 timeri->flags |= SNDRV_TIMER_IFLG_DEAD; 415 - spin_unlock_irq(&timer->lock); 416 397 } 417 398 418 399 if (!list_empty(&timeri->open_list)) { ··· 433 418 } 434 419 spin_unlock_irq(&timer->lock); 435 420 436 - /* remove slave links */ 437 - spin_lock_irq(&slave_active_lock); 438 - spin_lock(&timer->lock); 439 - timeri->timer = NULL; 440 - list_for_each_entry_safe(slave, tmp, &timeri->slave_list_head, 441 - open_list) { 442 - list_move_tail(&slave->open_list, &snd_timer_slave_list); 443 - timer->num_instances--; 444 - slave->master = NULL; 445 - slave->timer = NULL; 446 - list_del_init(&slave->ack_list); 447 - list_del_init(&slave->active_list); 448 - } 449 - spin_unlock(&timer->lock); 450 - spin_unlock_irq(&slave_active_lock); 421 + remove_slave_links(timeri, timer); 451 422 452 423 /* slave doesn't need to release timer resources below */ 453 424 if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE) ··· 460 459 if (snd_BUG_ON(!timeri)) 461 460 return; 462 461 463 - mutex_lock(&register_mutex); 464 - snd_timer_close_locked(timeri, &card_dev_to_put); 465 - mutex_unlock(&register_mutex); 462 + scoped_guard(mutex, &register_mutex) 463 + snd_timer_close_locked(timeri, &card_dev_to_put); 466 464 /* put_device() is called after unlock for avoiding deadlock */ 467 465 if (card_dev_to_put) 468 466 put_device(card_dev_to_put); ··· 480 480 { 481 481 struct snd_timer * timer; 482 482 unsigned long ret = 0; 483 - unsigned long flags; 484 483 485 484 if (timeri == NULL) 486 485 return 0; 487 486 timer = timeri->timer; 488 487 if (timer) { 489 - spin_lock_irqsave(&timer->lock, flags); 488 + guard(spinlock_irqsave)(&timer->lock); 490 489 ret = snd_timer_hw_resolution(timer); 491 - spin_unlock_irqrestore(&timer->lock, flags); 492 490 } 493 491 return ret; 494 492 } ··· 530 532 { 531 533 struct snd_timer *timer; 532 534 int result; 533 - unsigned long flags; 534 535 535 536 timer = timeri->timer; 536 537 if (!timer) 537 538 return -EINVAL; 538 539 539 - spin_lock_irqsave(&timer->lock, flags); 540 - if (timeri->flags & SNDRV_TIMER_IFLG_DEAD) { 541 - result = -EINVAL; 542 - goto unlock; 543 - } 544 - if (timer->card && timer->card->shutdown) { 545 - result = -ENODEV; 546 - goto unlock; 547 - } 540 + guard(spinlock_irqsave)(&timer->lock); 541 + if (timeri->flags & SNDRV_TIMER_IFLG_DEAD) 542 + return -EINVAL; 543 + if (timer->card && timer->card->shutdown) 544 + return -ENODEV; 548 545 if (timeri->flags & (SNDRV_TIMER_IFLG_RUNNING | 549 - SNDRV_TIMER_IFLG_START)) { 550 - result = -EBUSY; 551 - goto unlock; 552 - } 546 + SNDRV_TIMER_IFLG_START)) 547 + return -EBUSY; 553 548 554 549 if (start) 555 550 timeri->ticks = timeri->cticks = ticks; ··· 568 577 } 569 578 snd_timer_notify1(timeri, start ? SNDRV_TIMER_EVENT_START : 570 579 SNDRV_TIMER_EVENT_CONTINUE); 571 - unlock: 572 - spin_unlock_irqrestore(&timer->lock, flags); 573 580 return result; 574 581 } 575 582 ··· 575 586 static int snd_timer_start_slave(struct snd_timer_instance *timeri, 576 587 bool start) 577 588 { 578 - unsigned long flags; 579 - int err; 580 - 581 - spin_lock_irqsave(&slave_active_lock, flags); 582 - if (timeri->flags & SNDRV_TIMER_IFLG_DEAD) { 583 - err = -EINVAL; 584 - goto unlock; 585 - } 586 - if (timeri->flags & SNDRV_TIMER_IFLG_RUNNING) { 587 - err = -EBUSY; 588 - goto unlock; 589 - } 589 + guard(spinlock_irqsave)(&slave_active_lock); 590 + if (timeri->flags & SNDRV_TIMER_IFLG_DEAD) 591 + return -EINVAL; 592 + if (timeri->flags & SNDRV_TIMER_IFLG_RUNNING) 593 + return -EBUSY; 590 594 timeri->flags |= SNDRV_TIMER_IFLG_RUNNING; 591 595 if (timeri->master && timeri->timer) { 592 - spin_lock(&timeri->timer->lock); 596 + guard(spinlock)(&timeri->timer->lock); 593 597 list_add_tail(&timeri->active_list, 594 598 &timeri->master->slave_active_head); 595 599 snd_timer_notify1(timeri, start ? SNDRV_TIMER_EVENT_START : 596 600 SNDRV_TIMER_EVENT_CONTINUE); 597 - spin_unlock(&timeri->timer->lock); 598 601 } 599 - err = 1; /* delayed start */ 600 - unlock: 601 - spin_unlock_irqrestore(&slave_active_lock, flags); 602 - return err; 602 + return 1; /* delayed start */ 603 603 } 604 604 605 605 /* stop/pause a master timer */ 606 606 static int snd_timer_stop1(struct snd_timer_instance *timeri, bool stop) 607 607 { 608 608 struct snd_timer *timer; 609 - int result = 0; 610 - unsigned long flags; 611 609 612 610 timer = timeri->timer; 613 611 if (!timer) 614 612 return -EINVAL; 615 - spin_lock_irqsave(&timer->lock, flags); 613 + guard(spinlock_irqsave)(&timer->lock); 616 614 list_del_init(&timeri->ack_list); 617 615 list_del_init(&timeri->active_list); 618 616 if (!(timeri->flags & (SNDRV_TIMER_IFLG_RUNNING | 619 - SNDRV_TIMER_IFLG_START))) { 620 - result = -EBUSY; 621 - goto unlock; 622 - } 617 + SNDRV_TIMER_IFLG_START))) 618 + return -EBUSY; 623 619 if (timer->card && timer->card->shutdown) 624 - goto unlock; 620 + return 0; 625 621 if (stop) { 626 622 timeri->cticks = timeri->ticks; 627 623 timeri->pticks = 0; ··· 630 656 timeri->flags |= SNDRV_TIMER_IFLG_PAUSED; 631 657 snd_timer_notify1(timeri, stop ? SNDRV_TIMER_EVENT_STOP : 632 658 SNDRV_TIMER_EVENT_PAUSE); 633 - unlock: 634 - spin_unlock_irqrestore(&timer->lock, flags); 635 - return result; 659 + return 0; 636 660 } 637 661 638 662 /* stop/pause a slave timer */ 639 663 static int snd_timer_stop_slave(struct snd_timer_instance *timeri, bool stop) 640 664 { 641 - unsigned long flags; 642 665 bool running; 643 666 644 - spin_lock_irqsave(&slave_active_lock, flags); 667 + guard(spinlock_irqsave)(&slave_active_lock); 645 668 running = timeri->flags & SNDRV_TIMER_IFLG_RUNNING; 646 669 timeri->flags &= ~SNDRV_TIMER_IFLG_RUNNING; 647 670 if (timeri->timer) { 648 - spin_lock(&timeri->timer->lock); 671 + guard(spinlock)(&timeri->timer->lock); 649 672 list_del_init(&timeri->ack_list); 650 673 list_del_init(&timeri->active_list); 651 674 if (running) 652 675 snd_timer_notify1(timeri, stop ? SNDRV_TIMER_EVENT_STOP : 653 676 SNDRV_TIMER_EVENT_PAUSE); 654 - spin_unlock(&timeri->timer->lock); 655 677 } 656 - spin_unlock_irqrestore(&slave_active_lock, flags); 657 678 return running ? 0 : -EBUSY; 658 679 } 659 680 ··· 773 804 static void snd_timer_clear_callbacks(struct snd_timer *timer, 774 805 struct list_head *head) 775 806 { 776 - unsigned long flags; 777 - 778 - spin_lock_irqsave(&timer->lock, flags); 807 + guard(spinlock_irqsave)(&timer->lock); 779 808 while (!list_empty(head)) 780 809 list_del_init(head->next); 781 - spin_unlock_irqrestore(&timer->lock, flags); 782 810 } 783 811 784 812 /* ··· 785 819 static void snd_timer_work(struct work_struct *work) 786 820 { 787 821 struct snd_timer *timer = container_of(work, struct snd_timer, task_work); 788 - unsigned long flags; 789 822 790 823 if (timer->card && timer->card->shutdown) { 791 824 snd_timer_clear_callbacks(timer, &timer->sack_list_head); 792 825 return; 793 826 } 794 827 795 - spin_lock_irqsave(&timer->lock, flags); 828 + guard(spinlock_irqsave)(&timer->lock); 796 829 snd_timer_process_callbacks(timer, &timer->sack_list_head); 797 - spin_unlock_irqrestore(&timer->lock, flags); 798 830 } 799 831 800 832 /* ··· 806 842 struct snd_timer_instance *ti, *ts, *tmp; 807 843 unsigned long resolution; 808 844 struct list_head *ack_list_head; 809 - unsigned long flags; 810 - bool use_work = false; 811 845 812 846 if (timer == NULL) 813 847 return; ··· 815 853 return; 816 854 } 817 855 818 - spin_lock_irqsave(&timer->lock, flags); 856 + guard(spinlock_irqsave)(&timer->lock); 819 857 820 858 /* remember the current resolution */ 821 859 resolution = snd_timer_hw_resolution(timer); ··· 881 919 snd_timer_process_callbacks(timer, &timer->ack_list_head); 882 920 883 921 /* do we have any slow callbacks? */ 884 - use_work = !list_empty(&timer->sack_list_head); 885 - spin_unlock_irqrestore(&timer->lock, flags); 886 - 887 - if (use_work) 922 + if (!list_empty(&timer->sack_list_head)) 888 923 queue_work(system_highpri_wq, &timer->task_work); 889 924 } 890 925 EXPORT_SYMBOL(snd_timer_interrupt); ··· 947 988 if (!timer) 948 989 return 0; 949 990 950 - mutex_lock(&register_mutex); 991 + guard(mutex)(&register_mutex); 951 992 if (! list_empty(&timer->open_list_head)) { 952 993 struct list_head *p, *n; 953 994 struct snd_timer_instance *ti; ··· 959 1000 } 960 1001 } 961 1002 list_del(&timer->device_list); 962 - mutex_unlock(&register_mutex); 963 1003 964 1004 if (timer->private_free) 965 1005 timer->private_free(timer); ··· 983 1025 !timer->hw.resolution && timer->hw.c_resolution == NULL) 984 1026 return -EINVAL; 985 1027 986 - mutex_lock(&register_mutex); 1028 + guard(mutex)(&register_mutex); 987 1029 list_for_each_entry(timer1, &snd_timer_list, device_list) { 988 1030 if (timer1->tmr_class > timer->tmr_class) 989 1031 break; ··· 1004 1046 if (timer1->tmr_subdevice < timer->tmr_subdevice) 1005 1047 continue; 1006 1048 /* conflicts.. */ 1007 - mutex_unlock(&register_mutex); 1008 1049 return -EBUSY; 1009 1050 } 1010 1051 list_add_tail(&timer->device_list, &timer1->device_list); 1011 - mutex_unlock(&register_mutex); 1012 1052 return 0; 1013 1053 } 1014 1054 ··· 1015 1059 struct snd_timer *timer = device->device_data; 1016 1060 struct snd_timer_instance *ti; 1017 1061 1018 - mutex_lock(&register_mutex); 1062 + guard(mutex)(&register_mutex); 1019 1063 list_del_init(&timer->device_list); 1020 1064 /* wake up pending sleepers */ 1021 1065 list_for_each_entry(ti, &timer->open_list_head, open_list) { 1022 1066 if (ti->disconnect) 1023 1067 ti->disconnect(ti); 1024 1068 } 1025 - mutex_unlock(&register_mutex); 1026 1069 return 0; 1027 1070 } 1028 1071 1029 1072 void snd_timer_notify(struct snd_timer *timer, int event, struct timespec64 *tstamp) 1030 1073 { 1031 - unsigned long flags; 1032 1074 unsigned long resolution = 0; 1033 1075 struct snd_timer_instance *ti, *ts; 1034 1076 ··· 1037 1083 if (snd_BUG_ON(event < SNDRV_TIMER_EVENT_MSTART || 1038 1084 event > SNDRV_TIMER_EVENT_MRESUME)) 1039 1085 return; 1040 - spin_lock_irqsave(&timer->lock, flags); 1086 + guard(spinlock_irqsave)(&timer->lock); 1041 1087 if (event == SNDRV_TIMER_EVENT_MSTART || 1042 1088 event == SNDRV_TIMER_EVENT_MCONTINUE || 1043 1089 event == SNDRV_TIMER_EVENT_MRESUME) ··· 1049 1095 if (ts->ccallback) 1050 1096 ts->ccallback(ts, event, tstamp, resolution); 1051 1097 } 1052 - spin_unlock_irqrestore(&timer->lock, flags); 1053 1098 } 1054 1099 EXPORT_SYMBOL(snd_timer_notify); 1055 1100 ··· 1201 1248 struct snd_timer_instance *ti; 1202 1249 unsigned long resolution; 1203 1250 1204 - mutex_lock(&register_mutex); 1251 + guard(mutex)(&register_mutex); 1205 1252 list_for_each_entry(timer, &snd_timer_list, device_list) { 1206 1253 if (timer->card && timer->card->shutdown) 1207 1254 continue; ··· 1223 1270 timer->tmr_device, timer->tmr_subdevice); 1224 1271 } 1225 1272 snd_iprintf(buffer, "%s :", timer->name); 1226 - spin_lock_irq(&timer->lock); 1227 - resolution = snd_timer_hw_resolution(timer); 1228 - spin_unlock_irq(&timer->lock); 1273 + scoped_guard(spinlock_irq, &timer->lock) 1274 + resolution = snd_timer_hw_resolution(timer); 1229 1275 if (resolution) 1230 1276 snd_iprintf(buffer, " %lu.%03luus (%lu ticks)", 1231 1277 resolution / 1000, ··· 1240 1288 SNDRV_TIMER_IFLG_RUNNING)) 1241 1289 ? "running" : "stopped"); 1242 1290 } 1243 - mutex_unlock(&register_mutex); 1244 1291 } 1245 1292 1246 1293 static struct snd_info_entry *snd_timer_proc_entry; ··· 1280 1329 struct snd_timer_read *r; 1281 1330 int prev; 1282 1331 1283 - spin_lock(&tu->qlock); 1332 + guard(spinlock)(&tu->qlock); 1284 1333 if (tu->qused > 0) { 1285 1334 prev = tu->qtail == 0 ? tu->queue_size - 1 : tu->qtail - 1; 1286 1335 r = &tu->queue[prev]; ··· 1299 1348 tu->qused++; 1300 1349 } 1301 1350 __wake: 1302 - spin_unlock(&tu->qlock); 1303 1351 snd_kill_fasync(tu->fasync, SIGIO, POLL_IN); 1304 1352 wake_up(&tu->qchange_sleep); 1305 1353 } ··· 1322 1372 { 1323 1373 struct snd_timer_user *tu = timeri->callback_data; 1324 1374 struct snd_timer_tread64 r1; 1325 - unsigned long flags; 1326 1375 1327 1376 if (event >= SNDRV_TIMER_EVENT_START && 1328 1377 event <= SNDRV_TIMER_EVENT_PAUSE) ··· 1333 1384 r1.tstamp_sec = tstamp->tv_sec; 1334 1385 r1.tstamp_nsec = tstamp->tv_nsec; 1335 1386 r1.val = resolution; 1336 - spin_lock_irqsave(&tu->qlock, flags); 1337 - snd_timer_user_append_to_tqueue(tu, &r1); 1338 - spin_unlock_irqrestore(&tu->qlock, flags); 1387 + scoped_guard(spinlock_irqsave, &tu->qlock) 1388 + snd_timer_user_append_to_tqueue(tu, &r1); 1339 1389 snd_kill_fasync(tu->fasync, SIGIO, POLL_IN); 1340 1390 wake_up(&tu->qchange_sleep); 1341 1391 } ··· 1358 1410 1359 1411 memset(&r1, 0, sizeof(r1)); 1360 1412 memset(&tstamp, 0, sizeof(tstamp)); 1361 - spin_lock(&tu->qlock); 1362 - if ((tu->filter & ((1 << SNDRV_TIMER_EVENT_RESOLUTION) | 1363 - (1 << SNDRV_TIMER_EVENT_TICK))) == 0) { 1364 - spin_unlock(&tu->qlock); 1365 - return; 1366 - } 1367 - if (tu->last_resolution != resolution || ticks > 0) { 1368 - if (timer_tstamp_monotonic) 1369 - ktime_get_ts64(&tstamp); 1370 - else 1371 - ktime_get_real_ts64(&tstamp); 1372 - } 1373 - if ((tu->filter & (1 << SNDRV_TIMER_EVENT_RESOLUTION)) && 1374 - tu->last_resolution != resolution) { 1375 - r1.event = SNDRV_TIMER_EVENT_RESOLUTION; 1413 + scoped_guard(spinlock, &tu->qlock) { 1414 + if ((tu->filter & ((1 << SNDRV_TIMER_EVENT_RESOLUTION) | 1415 + (1 << SNDRV_TIMER_EVENT_TICK))) == 0) 1416 + return; 1417 + if (tu->last_resolution != resolution || ticks > 0) { 1418 + if (timer_tstamp_monotonic) 1419 + ktime_get_ts64(&tstamp); 1420 + else 1421 + ktime_get_real_ts64(&tstamp); 1422 + } 1423 + if ((tu->filter & (1 << SNDRV_TIMER_EVENT_RESOLUTION)) && 1424 + tu->last_resolution != resolution) { 1425 + r1.event = SNDRV_TIMER_EVENT_RESOLUTION; 1426 + r1.tstamp_sec = tstamp.tv_sec; 1427 + r1.tstamp_nsec = tstamp.tv_nsec; 1428 + r1.val = resolution; 1429 + snd_timer_user_append_to_tqueue(tu, &r1); 1430 + tu->last_resolution = resolution; 1431 + append++; 1432 + } 1433 + if ((tu->filter & (1 << SNDRV_TIMER_EVENT_TICK)) == 0) 1434 + break; 1435 + if (ticks == 0) 1436 + break; 1437 + if (tu->qused > 0) { 1438 + prev = tu->qtail == 0 ? tu->queue_size - 1 : tu->qtail - 1; 1439 + r = &tu->tqueue[prev]; 1440 + if (r->event == SNDRV_TIMER_EVENT_TICK) { 1441 + r->tstamp_sec = tstamp.tv_sec; 1442 + r->tstamp_nsec = tstamp.tv_nsec; 1443 + r->val += ticks; 1444 + append++; 1445 + break; 1446 + } 1447 + } 1448 + r1.event = SNDRV_TIMER_EVENT_TICK; 1376 1449 r1.tstamp_sec = tstamp.tv_sec; 1377 1450 r1.tstamp_nsec = tstamp.tv_nsec; 1378 - r1.val = resolution; 1451 + r1.val = ticks; 1379 1452 snd_timer_user_append_to_tqueue(tu, &r1); 1380 - tu->last_resolution = resolution; 1381 1453 append++; 1382 1454 } 1383 - if ((tu->filter & (1 << SNDRV_TIMER_EVENT_TICK)) == 0) 1384 - goto __wake; 1385 - if (ticks == 0) 1386 - goto __wake; 1387 - if (tu->qused > 0) { 1388 - prev = tu->qtail == 0 ? tu->queue_size - 1 : tu->qtail - 1; 1389 - r = &tu->tqueue[prev]; 1390 - if (r->event == SNDRV_TIMER_EVENT_TICK) { 1391 - r->tstamp_sec = tstamp.tv_sec; 1392 - r->tstamp_nsec = tstamp.tv_nsec; 1393 - r->val += ticks; 1394 - append++; 1395 - goto __wake; 1396 - } 1397 - } 1398 - r1.event = SNDRV_TIMER_EVENT_TICK; 1399 - r1.tstamp_sec = tstamp.tv_sec; 1400 - r1.tstamp_nsec = tstamp.tv_nsec; 1401 - r1.val = ticks; 1402 - snd_timer_user_append_to_tqueue(tu, &r1); 1403 - append++; 1404 - __wake: 1405 - spin_unlock(&tu->qlock); 1406 1455 if (append == 0) 1407 1456 return; 1408 1457 snd_kill_fasync(tu->fasync, SIGIO, POLL_IN); ··· 1421 1476 return -ENOMEM; 1422 1477 } 1423 1478 1424 - spin_lock_irq(&tu->qlock); 1479 + guard(spinlock_irq)(&tu->qlock); 1425 1480 kfree(tu->queue); 1426 1481 kfree(tu->tqueue); 1427 1482 tu->queue_size = size; 1428 1483 tu->queue = queue; 1429 1484 tu->tqueue = tqueue; 1430 1485 tu->qhead = tu->qtail = tu->qused = 0; 1431 - spin_unlock_irq(&tu->qlock); 1432 1486 1433 1487 return 0; 1434 1488 } ··· 1463 1519 if (file->private_data) { 1464 1520 tu = file->private_data; 1465 1521 file->private_data = NULL; 1466 - mutex_lock(&tu->ioctl_lock); 1467 - if (tu->timeri) { 1468 - snd_timer_close(tu->timeri); 1469 - snd_timer_instance_free(tu->timeri); 1522 + scoped_guard(mutex, &tu->ioctl_lock) { 1523 + if (tu->timeri) { 1524 + snd_timer_close(tu->timeri); 1525 + snd_timer_instance_free(tu->timeri); 1526 + } 1470 1527 } 1471 - mutex_unlock(&tu->ioctl_lock); 1472 1528 snd_fasync_free(tu->fasync); 1473 1529 kfree(tu->queue); 1474 1530 kfree(tu->tqueue); ··· 1503 1559 1504 1560 if (copy_from_user(&id, _tid, sizeof(id))) 1505 1561 return -EFAULT; 1506 - mutex_lock(&register_mutex); 1562 + guard(mutex)(&register_mutex); 1507 1563 if (id.dev_class < 0) { /* first item */ 1508 1564 if (list_empty(&snd_timer_list)) 1509 1565 snd_timer_user_zero_id(&id); ··· 1580 1636 snd_timer_user_zero_id(&id); 1581 1637 } 1582 1638 } 1583 - mutex_unlock(&register_mutex); 1584 1639 if (copy_to_user(_tid, &id, sizeof(*_tid))) 1585 1640 return -EFAULT; 1586 1641 return 0; ··· 1592 1649 struct snd_timer_id tid; 1593 1650 struct snd_timer *t; 1594 1651 struct list_head *p; 1595 - int err = 0; 1596 1652 1597 1653 ginfo = memdup_user(_ginfo, sizeof(*ginfo)); 1598 1654 if (IS_ERR(ginfo)) ··· 1600 1658 tid = ginfo->tid; 1601 1659 memset(ginfo, 0, sizeof(*ginfo)); 1602 1660 ginfo->tid = tid; 1603 - mutex_lock(&register_mutex); 1661 + guard(mutex)(&register_mutex); 1604 1662 t = snd_timer_find(&tid); 1605 - if (t != NULL) { 1606 - ginfo->card = t->card ? t->card->number : -1; 1607 - if (t->hw.flags & SNDRV_TIMER_HW_SLAVE) 1608 - ginfo->flags |= SNDRV_TIMER_FLG_SLAVE; 1609 - strscpy(ginfo->id, t->id, sizeof(ginfo->id)); 1610 - strscpy(ginfo->name, t->name, sizeof(ginfo->name)); 1611 - spin_lock_irq(&t->lock); 1663 + if (!t) 1664 + return -ENODEV; 1665 + ginfo->card = t->card ? t->card->number : -1; 1666 + if (t->hw.flags & SNDRV_TIMER_HW_SLAVE) 1667 + ginfo->flags |= SNDRV_TIMER_FLG_SLAVE; 1668 + strscpy(ginfo->id, t->id, sizeof(ginfo->id)); 1669 + strscpy(ginfo->name, t->name, sizeof(ginfo->name)); 1670 + scoped_guard(spinlock_irq, &t->lock) 1612 1671 ginfo->resolution = snd_timer_hw_resolution(t); 1613 - spin_unlock_irq(&t->lock); 1614 - if (t->hw.resolution_min > 0) { 1615 - ginfo->resolution_min = t->hw.resolution_min; 1616 - ginfo->resolution_max = t->hw.resolution_max; 1617 - } 1618 - list_for_each(p, &t->open_list_head) { 1619 - ginfo->clients++; 1620 - } 1621 - } else { 1622 - err = -ENODEV; 1672 + if (t->hw.resolution_min > 0) { 1673 + ginfo->resolution_min = t->hw.resolution_min; 1674 + ginfo->resolution_max = t->hw.resolution_max; 1623 1675 } 1624 - mutex_unlock(&register_mutex); 1625 - if (err >= 0 && copy_to_user(_ginfo, ginfo, sizeof(*ginfo))) 1626 - err = -EFAULT; 1627 - return err; 1676 + list_for_each(p, &t->open_list_head) { 1677 + ginfo->clients++; 1678 + } 1679 + if (copy_to_user(_ginfo, ginfo, sizeof(*ginfo))) 1680 + return -EFAULT; 1681 + return 0; 1628 1682 } 1629 1683 1630 1684 static int timer_set_gparams(struct snd_timer_gparams *gparams) 1631 1685 { 1632 1686 struct snd_timer *t; 1633 - int err; 1634 1687 1635 - mutex_lock(&register_mutex); 1688 + guard(mutex)(&register_mutex); 1636 1689 t = snd_timer_find(&gparams->tid); 1637 - if (!t) { 1638 - err = -ENODEV; 1639 - goto _error; 1640 - } 1641 - if (!list_empty(&t->open_list_head)) { 1642 - err = -EBUSY; 1643 - goto _error; 1644 - } 1645 - if (!t->hw.set_period) { 1646 - err = -ENOSYS; 1647 - goto _error; 1648 - } 1649 - err = t->hw.set_period(t, gparams->period_num, gparams->period_den); 1650 - _error: 1651 - mutex_unlock(&register_mutex); 1652 - return err; 1690 + if (!t) 1691 + return -ENODEV; 1692 + if (!list_empty(&t->open_list_head)) 1693 + return -EBUSY; 1694 + if (!t->hw.set_period) 1695 + return -ENOSYS; 1696 + return t->hw.set_period(t, gparams->period_num, gparams->period_den); 1653 1697 } 1654 1698 1655 1699 static int snd_timer_user_gparams(struct file *file, ··· 1661 1733 tid = gstatus.tid; 1662 1734 memset(&gstatus, 0, sizeof(gstatus)); 1663 1735 gstatus.tid = tid; 1664 - mutex_lock(&register_mutex); 1736 + guard(mutex)(&register_mutex); 1665 1737 t = snd_timer_find(&tid); 1666 1738 if (t != NULL) { 1667 - spin_lock_irq(&t->lock); 1739 + guard(spinlock_irq)(&t->lock); 1668 1740 gstatus.resolution = snd_timer_hw_resolution(t); 1669 1741 if (t->hw.precise_resolution) { 1670 1742 t->hw.precise_resolution(t, &gstatus.resolution_num, ··· 1673 1745 gstatus.resolution_num = gstatus.resolution; 1674 1746 gstatus.resolution_den = 1000000000uL; 1675 1747 } 1676 - spin_unlock_irq(&t->lock); 1677 1748 } else { 1678 1749 err = -ENODEV; 1679 1750 } 1680 - mutex_unlock(&register_mutex); 1681 1751 if (err >= 0 && copy_to_user(_gstatus, &gstatus, sizeof(gstatus))) 1682 1752 err = -EFAULT; 1683 1753 return err; ··· 1747 1821 info->flags |= SNDRV_TIMER_FLG_SLAVE; 1748 1822 strscpy(info->id, t->id, sizeof(info->id)); 1749 1823 strscpy(info->name, t->name, sizeof(info->name)); 1750 - spin_lock_irq(&t->lock); 1751 - info->resolution = snd_timer_hw_resolution(t); 1752 - spin_unlock_irq(&t->lock); 1824 + scoped_guard(spinlock_irq, &t->lock) 1825 + info->resolution = snd_timer_hw_resolution(t); 1753 1826 if (copy_to_user(_info, info, sizeof(*_info))) 1754 1827 return -EFAULT; 1755 1828 return 0; ··· 1809 1884 goto _end; 1810 1885 } 1811 1886 snd_timer_stop(tu->timeri); 1812 - spin_lock_irq(&t->lock); 1813 - tu->timeri->flags &= ~(SNDRV_TIMER_IFLG_AUTO| 1814 - SNDRV_TIMER_IFLG_EXCLUSIVE| 1815 - SNDRV_TIMER_IFLG_EARLY_EVENT); 1816 - if (params.flags & SNDRV_TIMER_PSFLG_AUTO) 1817 - tu->timeri->flags |= SNDRV_TIMER_IFLG_AUTO; 1818 - if (params.flags & SNDRV_TIMER_PSFLG_EXCLUSIVE) 1819 - tu->timeri->flags |= SNDRV_TIMER_IFLG_EXCLUSIVE; 1820 - if (params.flags & SNDRV_TIMER_PSFLG_EARLY_EVENT) 1821 - tu->timeri->flags |= SNDRV_TIMER_IFLG_EARLY_EVENT; 1822 - spin_unlock_irq(&t->lock); 1887 + scoped_guard(spinlock_irq, &t->lock) { 1888 + tu->timeri->flags &= ~(SNDRV_TIMER_IFLG_AUTO| 1889 + SNDRV_TIMER_IFLG_EXCLUSIVE| 1890 + SNDRV_TIMER_IFLG_EARLY_EVENT); 1891 + if (params.flags & SNDRV_TIMER_PSFLG_AUTO) 1892 + tu->timeri->flags |= SNDRV_TIMER_IFLG_AUTO; 1893 + if (params.flags & SNDRV_TIMER_PSFLG_EXCLUSIVE) 1894 + tu->timeri->flags |= SNDRV_TIMER_IFLG_EXCLUSIVE; 1895 + if (params.flags & SNDRV_TIMER_PSFLG_EARLY_EVENT) 1896 + tu->timeri->flags |= SNDRV_TIMER_IFLG_EARLY_EVENT; 1897 + } 1823 1898 if (params.queue_size > 0 && 1824 1899 (unsigned int)tu->queue_size != params.queue_size) { 1825 1900 err = realloc_user_queue(tu, params.queue_size); 1826 1901 if (err < 0) 1827 1902 goto _end; 1828 1903 } 1829 - spin_lock_irq(&tu->qlock); 1830 - tu->qhead = tu->qtail = tu->qused = 0; 1831 - if (tu->timeri->flags & SNDRV_TIMER_IFLG_EARLY_EVENT) { 1832 - if (tu->tread) { 1833 - struct snd_timer_tread64 tread; 1834 - memset(&tread, 0, sizeof(tread)); 1835 - tread.event = SNDRV_TIMER_EVENT_EARLY; 1836 - tread.tstamp_sec = 0; 1837 - tread.tstamp_nsec = 0; 1838 - tread.val = 0; 1839 - snd_timer_user_append_to_tqueue(tu, &tread); 1840 - } else { 1841 - struct snd_timer_read *r = &tu->queue[0]; 1842 - r->resolution = 0; 1843 - r->ticks = 0; 1844 - tu->qused++; 1845 - tu->qtail++; 1904 + scoped_guard(spinlock_irq, &tu->qlock) { 1905 + tu->qhead = tu->qtail = tu->qused = 0; 1906 + if (tu->timeri->flags & SNDRV_TIMER_IFLG_EARLY_EVENT) { 1907 + if (tu->tread) { 1908 + struct snd_timer_tread64 tread; 1909 + 1910 + memset(&tread, 0, sizeof(tread)); 1911 + tread.event = SNDRV_TIMER_EVENT_EARLY; 1912 + tread.tstamp_sec = 0; 1913 + tread.tstamp_nsec = 0; 1914 + tread.val = 0; 1915 + snd_timer_user_append_to_tqueue(tu, &tread); 1916 + } else { 1917 + struct snd_timer_read *r = &tu->queue[0]; 1918 + 1919 + r->resolution = 0; 1920 + r->ticks = 0; 1921 + tu->qused++; 1922 + tu->qtail++; 1923 + } 1846 1924 } 1925 + tu->filter = params.filter; 1926 + tu->ticks = params.ticks; 1847 1927 } 1848 - tu->filter = params.filter; 1849 - tu->ticks = params.ticks; 1850 - spin_unlock_irq(&tu->qlock); 1851 1928 err = 0; 1852 1929 _end: 1853 1930 if (copy_to_user(_params, &params, sizeof(params))) ··· 1872 1945 status.resolution = snd_timer_resolution(tu->timeri); 1873 1946 status.lost = tu->timeri->lost; 1874 1947 status.overrun = tu->overrun; 1875 - spin_lock_irq(&tu->qlock); 1876 - status.queue = tu->qused; 1877 - spin_unlock_irq(&tu->qlock); 1948 + scoped_guard(spinlock_irq, &tu->qlock) 1949 + status.queue = tu->qused; 1878 1950 if (copy_to_user(_status, &status, sizeof(status))) 1879 1951 return -EFAULT; 1880 1952 return 0; ··· 1894 1968 status.resolution = snd_timer_resolution(tu->timeri); 1895 1969 status.lost = tu->timeri->lost; 1896 1970 status.overrun = tu->overrun; 1897 - spin_lock_irq(&tu->qlock); 1898 - status.queue = tu->qused; 1899 - spin_unlock_irq(&tu->qlock); 1971 + scoped_guard(spinlock_irq, &tu->qlock) 1972 + status.queue = tu->qused; 1900 1973 if (copy_to_user(_status, &status, sizeof(status))) 1901 1974 return -EFAULT; 1902 1975 return 0; ··· 2053 2128 unsigned long arg) 2054 2129 { 2055 2130 struct snd_timer_user *tu = file->private_data; 2056 - long ret; 2057 2131 2058 - mutex_lock(&tu->ioctl_lock); 2059 - ret = __snd_timer_user_ioctl(file, cmd, arg, false); 2060 - mutex_unlock(&tu->ioctl_lock); 2061 - return ret; 2132 + guard(mutex)(&tu->ioctl_lock); 2133 + return __snd_timer_user_ioctl(file, cmd, arg, false); 2062 2134 } 2063 2135 2064 2136 static int snd_timer_user_fasync(int fd, struct file * file, int on) ··· 2182 2260 poll_wait(file, &tu->qchange_sleep, wait); 2183 2261 2184 2262 mask = 0; 2185 - spin_lock_irq(&tu->qlock); 2263 + guard(spinlock_irq)(&tu->qlock); 2186 2264 if (tu->qused) 2187 2265 mask |= EPOLLIN | EPOLLRDNORM; 2188 2266 if (tu->disconnected) 2189 2267 mask |= EPOLLERR; 2190 - spin_unlock_irq(&tu->qlock); 2191 2268 2192 2269 return mask; 2193 2270 }
+2 -5
sound/core/timer_compat.c
··· 115 115 unsigned long arg) 116 116 { 117 117 struct snd_timer_user *tu = file->private_data; 118 - long ret; 119 118 120 - mutex_lock(&tu->ioctl_lock); 121 - ret = __snd_timer_user_ioctl_compat(file, cmd, arg); 122 - mutex_unlock(&tu->ioctl_lock); 123 - return ret; 119 + guard(mutex)(&tu->ioctl_lock); 120 + return __snd_timer_user_ioctl_compat(file, cmd, arg); 124 121 }