Sun Feb 23 07:17:01 2020 UTC ()
Prevent a race between audiodetach and fileops methods using psref(9).
Fix PR kern/54427.
Thank you so much riastradh@


(isaki)
diff -r1.55 -r1.56 src/sys/dev/audio/audio.c
diff -r1.9 -r1.10 src/sys/dev/audio/audiodef.h
diff -r1.7 -r1.8 src/sys/dev/audio/audiovar.h

cvs diff -r1.55 -r1.56 src/sys/dev/audio/audio.c (expand / switch to unified diff)

--- src/sys/dev/audio/audio.c 2020/02/23 04:24:56 1.55
+++ src/sys/dev/audio/audio.c 2020/02/23 07:17:01 1.56
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: audio.c,v 1.55 2020/02/23 04:24:56 isaki Exp $ */ 1/* $NetBSD: audio.c,v 1.56 2020/02/23 07:17:01 isaki Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2008 The NetBSD Foundation, Inc. 4 * Copyright (c) 2008 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Andrew Doran. 8 * by Andrew Doran.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -132,27 +132,27 @@ @@ -132,27 +132,27 @@
132 * these may be also called after attach, the thread lock is required. 132 * these may be also called after attach, the thread lock is required.
133 * 133 *
134 * In addition, there is an additional lock. 134 * In addition, there is an additional lock.
135 * 135 *
136 * - track->lock. This is an atomic variable and is similar to the 136 * - track->lock. This is an atomic variable and is similar to the
137 * "interrupt lock". This is one for each track. If any thread context 137 * "interrupt lock". This is one for each track. If any thread context
138 * (and software interrupt context) and hardware interrupt context who 138 * (and software interrupt context) and hardware interrupt context who
139 * want to access some variables on this track, they must acquire this 139 * want to access some variables on this track, they must acquire this
140 * lock before. It protects track's consistency between hardware 140 * lock before. It protects track's consistency between hardware
141 * interrupt context and others. 141 * interrupt context and others.
142 */ 142 */
143 143
144#include <sys/cdefs.h> 144#include <sys/cdefs.h>
145__KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.55 2020/02/23 04:24:56 isaki Exp $"); 145__KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.56 2020/02/23 07:17:01 isaki Exp $");
146 146
147#ifdef _KERNEL_OPT 147#ifdef _KERNEL_OPT
148#include "audio.h" 148#include "audio.h"
149#include "midi.h" 149#include "midi.h"
150#endif 150#endif
151 151
152#if NAUDIO > 0 152#if NAUDIO > 0
153 153
154#include <sys/types.h> 154#include <sys/types.h>
155#include <sys/param.h> 155#include <sys/param.h>
156#include <sys/atomic.h> 156#include <sys/atomic.h>
157#include <sys/audioio.h> 157#include <sys/audioio.h>
158#include <sys/conf.h> 158#include <sys/conf.h>
@@ -489,58 +489,60 @@ static bool audio_suspend(device_t dv, c @@ -489,58 +489,60 @@ static bool audio_suspend(device_t dv, c
489static bool audio_resume(device_t dv, const pmf_qual_t *); 489static bool audio_resume(device_t dv, const pmf_qual_t *);
490static void audio_volume_down(device_t); 490static void audio_volume_down(device_t);
491static void audio_volume_up(device_t); 491static void audio_volume_up(device_t);
492static void audio_volume_toggle(device_t); 492static void audio_volume_toggle(device_t);
493 493
494static void audio_mixer_capture(struct audio_softc *); 494static void audio_mixer_capture(struct audio_softc *);
495static void audio_mixer_restore(struct audio_softc *); 495static void audio_mixer_restore(struct audio_softc *);
496 496
497static void audio_softintr_rd(void *); 497static void audio_softintr_rd(void *);
498static void audio_softintr_wr(void *); 498static void audio_softintr_wr(void *);
499 499
500static int audio_enter_exclusive(struct audio_softc *); 500static int audio_enter_exclusive(struct audio_softc *);
501static void audio_exit_exclusive(struct audio_softc *); 501static void audio_exit_exclusive(struct audio_softc *);
 502static struct audio_softc *audio_file_enter(audio_file_t *, struct psref *);
 503static void audio_file_exit(struct audio_softc *, struct psref *);
502static int audio_track_waitio(struct audio_softc *, audio_track_t *); 504static int audio_track_waitio(struct audio_softc *, audio_track_t *);
503 505
504static int audioclose(struct file *); 506static int audioclose(struct file *);
505static int audioread(struct file *, off_t *, struct uio *, kauth_cred_t, int); 507static int audioread(struct file *, off_t *, struct uio *, kauth_cred_t, int);
506static int audiowrite(struct file *, off_t *, struct uio *, kauth_cred_t, int); 508static int audiowrite(struct file *, off_t *, struct uio *, kauth_cred_t, int);
507static int audioioctl(struct file *, u_long, void *); 509static int audioioctl(struct file *, u_long, void *);
508static int audiopoll(struct file *, int); 510static int audiopoll(struct file *, int);
509static int audiokqfilter(struct file *, struct knote *); 511static int audiokqfilter(struct file *, struct knote *);
510static int audiommap(struct file *, off_t *, size_t, int, int *, int *, 512static int audiommap(struct file *, off_t *, size_t, int, int *, int *,
511 struct uvm_object **, int *); 513 struct uvm_object **, int *);
512static int audiostat(struct file *, struct stat *); 514static int audiostat(struct file *, struct stat *);
513 515
514static void filt_audiowrite_detach(struct knote *); 516static void filt_audiowrite_detach(struct knote *);
515static int filt_audiowrite_event(struct knote *, long); 517static int filt_audiowrite_event(struct knote *, long);
516static void filt_audioread_detach(struct knote *); 518static void filt_audioread_detach(struct knote *);
517static int filt_audioread_event(struct knote *, long); 519static int filt_audioread_event(struct knote *, long);
518 520
519static int audio_open(dev_t, struct audio_softc *, int, int, struct lwp *, 521static int audio_open(dev_t, struct audio_softc *, int, int, struct lwp *,
520 audio_file_t **); 522 audio_file_t **);
521static int audio_close(struct audio_softc *, audio_file_t *); 523static int audio_close(struct audio_softc *, audio_file_t *);
 524static int audio_unlink(struct audio_softc *, audio_file_t *);
522static int audio_read(struct audio_softc *, struct uio *, int, audio_file_t *); 525static int audio_read(struct audio_softc *, struct uio *, int, audio_file_t *);
523static int audio_write(struct audio_softc *, struct uio *, int, audio_file_t *); 526static int audio_write(struct audio_softc *, struct uio *, int, audio_file_t *);
524static void audio_file_clear(struct audio_softc *, audio_file_t *); 527static void audio_file_clear(struct audio_softc *, audio_file_t *);
525static int audio_ioctl(dev_t, struct audio_softc *, u_long, void *, int, 528static int audio_ioctl(dev_t, struct audio_softc *, u_long, void *, int,
526 struct lwp *, audio_file_t *); 529 struct lwp *, audio_file_t *);
527static int audio_poll(struct audio_softc *, int, struct lwp *, audio_file_t *); 530static int audio_poll(struct audio_softc *, int, struct lwp *, audio_file_t *);
528static int audio_kqfilter(struct audio_softc *, audio_file_t *, struct knote *); 531static int audio_kqfilter(struct audio_softc *, audio_file_t *, struct knote *);
529static int audio_mmap(struct audio_softc *, off_t *, size_t, int, int *, int *, 532static int audio_mmap(struct audio_softc *, off_t *, size_t, int, int *, int *,
530 struct uvm_object **, int *, audio_file_t *); 533 struct uvm_object **, int *, audio_file_t *);
531 534
532static int audioctl_open(dev_t, struct audio_softc *, int, int, struct lwp *); 535static int audioctl_open(dev_t, struct audio_softc *, int, int, struct lwp *);
533static int audioctl_close(struct audio_softc *, audio_file_t *); 
534 536
535static void audio_pintr(void *); 537static void audio_pintr(void *);
536static void audio_rintr(void *); 538static void audio_rintr(void *);
537 539
538static int audio_query_devinfo(struct audio_softc *, mixer_devinfo_t *); 540static int audio_query_devinfo(struct audio_softc *, mixer_devinfo_t *);
539 541
540static __inline int audio_track_readablebytes(const audio_track_t *); 542static __inline int audio_track_readablebytes(const audio_track_t *);
541static int audio_file_setinfo(struct audio_softc *, audio_file_t *, 543static int audio_file_setinfo(struct audio_softc *, audio_file_t *,
542 const struct audio_info *); 544 const struct audio_info *);
543static int audio_track_setinfo_check(audio_format2_t *, 545static int audio_track_setinfo_check(audio_format2_t *,
544 const struct audio_prinfo *, const audio_format2_t *); 546 const struct audio_prinfo *, const audio_format2_t *);
545static void audio_track_setinfo_water(audio_track_t *, 547static void audio_track_setinfo_water(audio_track_t *,
546 const struct audio_info *); 548 const struct audio_info *);
@@ -800,26 +802,28 @@ static const audio_encoding_t audio_enco @@ -800,26 +802,28 @@ static const audio_encoding_t audio_enco
800static const struct portname itable[] = { 802static const struct portname itable[] = {
801 { AudioNmicrophone, AUDIO_MICROPHONE }, 803 { AudioNmicrophone, AUDIO_MICROPHONE },
802 { AudioNline, AUDIO_LINE_IN }, 804 { AudioNline, AUDIO_LINE_IN },
803 { AudioNcd, AUDIO_CD }, 805 { AudioNcd, AUDIO_CD },
804 { 0, 0 } 806 { 0, 0 }
805}; 807};
806static const struct portname otable[] = { 808static const struct portname otable[] = {
807 { AudioNspeaker, AUDIO_SPEAKER }, 809 { AudioNspeaker, AUDIO_SPEAKER },
808 { AudioNheadphone, AUDIO_HEADPHONE }, 810 { AudioNheadphone, AUDIO_HEADPHONE },
809 { AudioNline, AUDIO_LINE_OUT }, 811 { AudioNline, AUDIO_LINE_OUT },
810 { 0, 0 } 812 { 0, 0 }
811}; 813};
812 814
 815static struct psref_class *audio_psref_class __read_mostly;
 816
813CFATTACH_DECL3_NEW(audio, sizeof(struct audio_softc), 817CFATTACH_DECL3_NEW(audio, sizeof(struct audio_softc),
814 audiomatch, audioattach, audiodetach, audioactivate, audiorescan, 818 audiomatch, audioattach, audiodetach, audioactivate, audiorescan,
815 audiochilddet, DVF_DETACH_SHUTDOWN); 819 audiochilddet, DVF_DETACH_SHUTDOWN);
816 820
817static int 821static int
818audiomatch(device_t parent, cfdata_t match, void *aux) 822audiomatch(device_t parent, cfdata_t match, void *aux)
819{ 823{
820 struct audio_attach_args *sa; 824 struct audio_attach_args *sa;
821 825
822 sa = aux; 826 sa = aux;
823 DPRINTF(1, "%s: type=%d sa=%p hw=%p\n", 827 DPRINTF(1, "%s: type=%d sa=%p hw=%p\n",
824 __func__, sa->type, sa, sa->hwif); 828 __func__, sa->type, sa, sa->hwif);
825 return (sa->type == AUDIODEV_TYPE_AUDIO) ? 1 : 0; 829 return (sa->type == AUDIODEV_TYPE_AUDIO) ? 1 : 0;
@@ -988,26 +992,29 @@ audioattach(device_t parent, device_t se @@ -988,26 +992,29 @@ audioattach(device_t parent, device_t se
988 992
989 /* 993 /*
990 * Init track mixers. If at least one direction is available on 994 * Init track mixers. If at least one direction is available on
991 * attach time, we assume a success. 995 * attach time, we assume a success.
992 */ 996 */
993 error = audio_mixers_init(sc, mode, &phwfmt, &rhwfmt, &pfil, &rfil); 997 error = audio_mixers_init(sc, mode, &phwfmt, &rhwfmt, &pfil, &rfil);
994 mutex_exit(sc->sc_lock); 998 mutex_exit(sc->sc_lock);
995 if (sc->sc_pmixer == NULL && sc->sc_rmixer == NULL) { 999 if (sc->sc_pmixer == NULL && sc->sc_rmixer == NULL) {
996 aprint_error_dev(self, "audio_mixers_init failed, " 1000 aprint_error_dev(self, "audio_mixers_init failed, "
997 "error = %d\n", error); 1001 "error = %d\n", error);
998 goto bad; 1002 goto bad;
999 } 1003 }
1000 1004
 1005 sc->sc_psz = pserialize_create();
 1006 psref_target_init(&sc->sc_psref, audio_psref_class);
 1007
1001 selinit(&sc->sc_wsel); 1008 selinit(&sc->sc_wsel);
1002 selinit(&sc->sc_rsel); 1009 selinit(&sc->sc_rsel);
1003 1010
1004 /* Initial parameter of /dev/sound */ 1011 /* Initial parameter of /dev/sound */
1005 sc->sc_sound_pparams = params_to_format2(&audio_default); 1012 sc->sc_sound_pparams = params_to_format2(&audio_default);
1006 sc->sc_sound_rparams = params_to_format2(&audio_default); 1013 sc->sc_sound_rparams = params_to_format2(&audio_default);
1007 sc->sc_sound_ppause = false; 1014 sc->sc_sound_ppause = false;
1008 sc->sc_sound_rpause = false; 1015 sc->sc_sound_rpause = false;
1009 1016
1010 /* XXX TODO: consider about sc_ai */ 1017 /* XXX TODO: consider about sc_ai */
1011 1018
1012 mixer_init(sc); 1019 mixer_init(sc);
1013 TRACE(2, "inputs ports=0x%x, input master=%d, " 1020 TRACE(2, "inputs ports=0x%x, input master=%d, "
@@ -1245,65 +1252,81 @@ audioactivate(device_t self, enum devact @@ -1245,65 +1252,81 @@ audioactivate(device_t self, enum devact
1245 sc->sc_dying = true; 1252 sc->sc_dying = true;
1246 cv_broadcast(&sc->sc_exlockcv); 1253 cv_broadcast(&sc->sc_exlockcv);
1247 mutex_exit(sc->sc_lock); 1254 mutex_exit(sc->sc_lock);
1248 return 0; 1255 return 0;
1249 default: 1256 default:
1250 return EOPNOTSUPP; 1257 return EOPNOTSUPP;
1251 } 1258 }
1252} 1259}
1253 1260
1254static int 1261static int
1255audiodetach(device_t self, int flags) 1262audiodetach(device_t self, int flags)
1256{ 1263{
1257 struct audio_softc *sc; 1264 struct audio_softc *sc;
1258 int maj, mn; 1265 struct audio_file *file;
1259 int error; 1266 int error;
1260 1267
1261 sc = device_private(self); 1268 sc = device_private(self);
1262 TRACE(2, "flags=%d", flags); 1269 TRACE(2, "flags=%d", flags);
1263 1270
1264 /* device is not initialized */ 1271 /* device is not initialized */
1265 if (sc->hw_if == NULL) 1272 if (sc->hw_if == NULL)
1266 return 0; 1273 return 0;
1267 1274
1268 /* Start draining existing accessors of the device. */ 1275 /* Start draining existing accessors of the device. */
1269 error = config_detach_children(self, flags); 1276 error = config_detach_children(self, flags);
1270 if (error) 1277 if (error)
1271 return error; 1278 return error;
1272 1279
 1280 /* delete sysctl nodes */
 1281 sysctl_teardown(&sc->sc_log);
 1282
1273 mutex_enter(sc->sc_lock); 1283 mutex_enter(sc->sc_lock);
1274 sc->sc_dying = true; 1284 sc->sc_dying = true;
1275 cv_broadcast(&sc->sc_exlockcv); 1285 cv_broadcast(&sc->sc_exlockcv);
1276 if (sc->sc_pmixer) 1286 if (sc->sc_pmixer)
1277 cv_broadcast(&sc->sc_pmixer->outcv); 1287 cv_broadcast(&sc->sc_pmixer->outcv);
1278 if (sc->sc_rmixer) 1288 if (sc->sc_rmixer)
1279 cv_broadcast(&sc->sc_rmixer->outcv); 1289 cv_broadcast(&sc->sc_rmixer->outcv);
1280 mutex_exit(sc->sc_lock); 
1281 1290
1282 /* delete sysctl nodes */ 1291 /* Prevent new users */
1283 sysctl_teardown(&sc->sc_log); 1292 SLIST_FOREACH(file, &sc->sc_files, entry) {
 1293 atomic_store_relaxed(&file->dying, true);
 1294 }
 1295
 1296 /*
 1297 * Wait for existing users to drain.
 1298 * - pserialize_perform waits for all pserialize_read sections on
 1299 * all CPUs; after this, no more new psref_acquire can happen.
 1300 * - psref_target_destroy waits for all extant acquired psrefs to
 1301 * be psref_released.
 1302 */
 1303 pserialize_perform(sc->sc_psz);
 1304 mutex_exit(sc->sc_lock);
 1305 psref_target_destroy(&sc->sc_psref, audio_psref_class);
1284 1306
1285 /* locate the major number */ 1307 /*
1286 maj = cdevsw_lookup_major(&audio_cdevsw); 1308 * We are now guaranteed that there are no calls to audio fileops
 1309 * that hold sc, and any new calls with files that were for sc will
 1310 * fail. Thus, we now have exclusive access to the softc.
 1311 */
1287 1312
1288 /* 1313 /*
1289 * Nuke the vnodes for any open instances (calls close). 1314 * Nuke all open instances.
1290 * Will wait until any activity on the device nodes has ceased. 1315 * Here, we no longer need any locks to traverse sc_files.
1291 */ 1316 */
1292 mn = device_unit(self); 1317 while ((file = SLIST_FIRST(&sc->sc_files)) != NULL) {
1293 vdevgone(maj, mn | SOUND_DEVICE, mn | SOUND_DEVICE, VCHR); 1318 audio_unlink(sc, file);
1294 vdevgone(maj, mn | AUDIO_DEVICE, mn | AUDIO_DEVICE, VCHR); 1319 }
1295 vdevgone(maj, mn | AUDIOCTL_DEVICE, mn | AUDIOCTL_DEVICE, VCHR); 
1296 vdevgone(maj, mn | MIXER_DEVICE, mn | MIXER_DEVICE, VCHR); 
1297 1320
1298 pmf_event_deregister(self, PMFE_AUDIO_VOLUME_DOWN, 1321 pmf_event_deregister(self, PMFE_AUDIO_VOLUME_DOWN,
1299 audio_volume_down, true); 1322 audio_volume_down, true);
1300 pmf_event_deregister(self, PMFE_AUDIO_VOLUME_UP, 1323 pmf_event_deregister(self, PMFE_AUDIO_VOLUME_UP,
1301 audio_volume_up, true); 1324 audio_volume_up, true);
1302 pmf_event_deregister(self, PMFE_AUDIO_VOLUME_TOGGLE, 1325 pmf_event_deregister(self, PMFE_AUDIO_VOLUME_TOGGLE,
1303 audio_volume_toggle, true); 1326 audio_volume_toggle, true);
1304 1327
1305#ifdef AUDIO_PM_IDLE 1328#ifdef AUDIO_PM_IDLE
1306 callout_halt(&sc->sc_idle_counter, sc->sc_lock); 1329 callout_halt(&sc->sc_idle_counter, sc->sc_lock);
1307 1330
1308 device_active_deregister(self, audio_activity); 1331 device_active_deregister(self, audio_activity);
1309#endif 1332#endif
@@ -1430,26 +1453,68 @@ static void @@ -1430,26 +1453,68 @@ static void
1430audio_exit_exclusive(struct audio_softc *sc) 1453audio_exit_exclusive(struct audio_softc *sc)
1431{ 1454{
1432 1455
1433 KASSERT(mutex_owned(sc->sc_lock)); 1456 KASSERT(mutex_owned(sc->sc_lock));
1434 KASSERT(sc->sc_exlock); 1457 KASSERT(sc->sc_exlock);
1435 1458
1436 /* Leave critical section */ 1459 /* Leave critical section */
1437 sc->sc_exlock = 0; 1460 sc->sc_exlock = 0;
1438 cv_broadcast(&sc->sc_exlockcv); 1461 cv_broadcast(&sc->sc_exlockcv);
1439 mutex_exit(sc->sc_lock); 1462 mutex_exit(sc->sc_lock);
1440} 1463}
1441 1464
1442/* 1465/*
 1466 * Acquire sc from file, and increment the psref count.
 1467 * If successful, returns sc. Otherwise returns NULL.
 1468 */
 1469struct audio_softc *
 1470audio_file_enter(audio_file_t *file, struct psref *refp)
 1471{
 1472 int s;
 1473 bool dying;
 1474
 1475 /* psref(9) forbids to migrate CPUs */
 1476 curlwp_bind();
 1477
 1478 /* Block audiodetach while we acquire a reference */
 1479 s = pserialize_read_enter();
 1480
 1481 /* If close or audiodetach already ran, tough -- no more audio */
 1482 dying = atomic_load_relaxed(&file->dying);
 1483 if (dying) {
 1484 pserialize_read_exit(s);
 1485 return NULL;
 1486 }
 1487
 1488 /* Acquire a reference */
 1489 psref_acquire(refp, &file->sc->sc_psref, audio_psref_class);
 1490
 1491 /* Now sc won't go away until we drop the reference count */
 1492 pserialize_read_exit(s);
 1493
 1494 return file->sc;
 1495}
 1496
 1497/*
 1498 * Decrement the psref count.
 1499 */
 1500void
 1501audio_file_exit(struct audio_softc *sc, struct psref *refp)
 1502{
 1503
 1504 psref_release(refp, &sc->sc_psref, audio_psref_class);
 1505}
 1506
 1507/*
1443 * Wait for I/O to complete, releasing sc_lock. 1508 * Wait for I/O to complete, releasing sc_lock.
1444 * Must be called with sc_lock held. 1509 * Must be called with sc_lock held.
1445 */ 1510 */
1446static int 1511static int
1447audio_track_waitio(struct audio_softc *sc, audio_track_t *track) 1512audio_track_waitio(struct audio_softc *sc, audio_track_t *track)
1448{ 1513{
1449 int error; 1514 int error;
1450 1515
1451 KASSERT(track); 1516 KASSERT(track);
1452 KASSERT(mutex_owned(sc->sc_lock)); 1517 KASSERT(mutex_owned(sc->sc_lock));
1453 1518
1454 /* Wait for pending I/O to complete. */ 1519 /* Wait for pending I/O to complete. */
1455 error = cv_timedwait_sig(&track->mixer->outcv, sc->sc_lock, 1520 error = cv_timedwait_sig(&track->mixer->outcv, sc->sc_lock,
@@ -1530,274 +1595,329 @@ audioopen(dev_t dev, int flags, int ifmt @@ -1530,274 +1595,329 @@ audioopen(dev_t dev, int flags, int ifmt
1530 default: 1595 default:
1531 error = ENXIO; 1596 error = ENXIO;
1532 break; 1597 break;
1533 } 1598 }
1534 audio_exit_exclusive(sc); 1599 audio_exit_exclusive(sc);
1535 1600
1536 return error; 1601 return error;
1537} 1602}
1538 1603
1539static int 1604static int
1540audioclose(struct file *fp) 1605audioclose(struct file *fp)
1541{ 1606{
1542 struct audio_softc *sc; 1607 struct audio_softc *sc;
 1608 struct psref sc_ref;
1543 audio_file_t *file; 1609 audio_file_t *file;
1544 int error; 1610 int error;
1545 dev_t dev; 1611 dev_t dev;
1546 1612
1547 KASSERT(fp->f_audioctx); 1613 KASSERT(fp->f_audioctx);
1548 file = fp->f_audioctx; 1614 file = fp->f_audioctx;
1549 sc = file->sc; 
1550 dev = file->dev; 1615 dev = file->dev;
 1616 error = 0;
1551 1617
1552 /* audio_{enter,exit}_exclusive() is called by lower audio_close() */ 1618 /*
 1619 * audioclose() must
 1620 * - unplug track from the trackmixer (and unplug anything from softc),
 1621 * if sc exists.
 1622 * - free all memory objects, regardless of sc.
 1623 */
1553 1624
1554 device_active(sc->sc_dev, DVA_SYSTEM); 1625 sc = audio_file_enter(file, &sc_ref);
1555 switch (AUDIODEV(dev)) { 1626 if (sc) {
1556 case SOUND_DEVICE: 1627 switch (AUDIODEV(dev)) {
1557 case AUDIO_DEVICE: 1628 case SOUND_DEVICE:
1558 error = audio_close(sc, file); 1629 case AUDIO_DEVICE:
1559 break; 1630 error = audio_close(sc, file);
1560 case AUDIOCTL_DEVICE: 1631 break;
1561 error = audioctl_close(sc, file); 1632 case AUDIOCTL_DEVICE:
1562 break; 1633 error = 0;
1563 case MIXER_DEVICE: 1634 break;
1564 error = mixer_close(sc, file); 1635 case MIXER_DEVICE:
1565 break; 1636 error = mixer_close(sc, file);
1566 default: 1637 break;
1567 error = ENXIO; 1638 default:
1568 break; 1639 error = ENXIO;
 1640 break;
 1641 }
 1642
 1643 audio_file_exit(sc, &sc_ref);
1569 } 1644 }
1570 /* f_audioctx has already been freed in lower *_close() */ 1645
 1646 /* Free memory objects anyway */
 1647 TRACEF(2, file, "free memory");
 1648 if (file->ptrack)
 1649 audio_track_destroy(file->ptrack);
 1650 if (file->rtrack)
 1651 audio_track_destroy(file->rtrack);
 1652 kmem_free(file, sizeof(*file));
1571 fp->f_audioctx = NULL; 1653 fp->f_audioctx = NULL;
1572 1654
1573 return error; 1655 return error;
1574} 1656}
1575 1657
1576static int 1658static int
1577audioread(struct file *fp, off_t *offp, struct uio *uio, kauth_cred_t cred, 1659audioread(struct file *fp, off_t *offp, struct uio *uio, kauth_cred_t cred,
1578 int ioflag) 1660 int ioflag)
1579{ 1661{
1580 struct audio_softc *sc; 1662 struct audio_softc *sc;
 1663 struct psref sc_ref;
1581 audio_file_t *file; 1664 audio_file_t *file;
1582 int error; 1665 int error;
1583 dev_t dev; 1666 dev_t dev;
1584 1667
1585 KASSERT(fp->f_audioctx); 1668 KASSERT(fp->f_audioctx);
1586 file = fp->f_audioctx; 1669 file = fp->f_audioctx;
1587 sc = file->sc; 
1588 dev = file->dev; 1670 dev = file->dev;
1589 1671
 1672 sc = audio_file_enter(file, &sc_ref);
 1673 if (sc == NULL)
 1674 return EIO;
 1675
1590 if (fp->f_flag & O_NONBLOCK) 1676 if (fp->f_flag & O_NONBLOCK)
1591 ioflag |= IO_NDELAY; 1677 ioflag |= IO_NDELAY;
1592 1678
1593 switch (AUDIODEV(dev)) { 1679 switch (AUDIODEV(dev)) {
1594 case SOUND_DEVICE: 1680 case SOUND_DEVICE:
1595 case AUDIO_DEVICE: 1681 case AUDIO_DEVICE:
1596 error = audio_read(sc, uio, ioflag, file); 1682 error = audio_read(sc, uio, ioflag, file);
1597 break; 1683 break;
1598 case AUDIOCTL_DEVICE: 1684 case AUDIOCTL_DEVICE:
1599 case MIXER_DEVICE: 1685 case MIXER_DEVICE:
1600 error = ENODEV; 1686 error = ENODEV;
1601 break; 1687 break;
1602 default: 1688 default:
1603 error = ENXIO; 1689 error = ENXIO;
1604 break; 1690 break;
1605 } 1691 }
1606 1692
 1693 audio_file_exit(sc, &sc_ref);
1607 return error; 1694 return error;
1608} 1695}
1609 1696
1610static int 1697static int
1611audiowrite(struct file *fp, off_t *offp, struct uio *uio, kauth_cred_t cred, 1698audiowrite(struct file *fp, off_t *offp, struct uio *uio, kauth_cred_t cred,
1612 int ioflag) 1699 int ioflag)
1613{ 1700{
1614 struct audio_softc *sc; 1701 struct audio_softc *sc;
 1702 struct psref sc_ref;
1615 audio_file_t *file; 1703 audio_file_t *file;
1616 int error; 1704 int error;
1617 dev_t dev; 1705 dev_t dev;
1618 1706
1619 KASSERT(fp->f_audioctx); 1707 KASSERT(fp->f_audioctx);
1620 file = fp->f_audioctx; 1708 file = fp->f_audioctx;
1621 sc = file->sc; 
1622 dev = file->dev; 1709 dev = file->dev;
1623 1710
 1711 sc = audio_file_enter(file, &sc_ref);
 1712 if (sc == NULL)
 1713 return EIO;
 1714
1624 if (fp->f_flag & O_NONBLOCK) 1715 if (fp->f_flag & O_NONBLOCK)
1625 ioflag |= IO_NDELAY; 1716 ioflag |= IO_NDELAY;
1626 1717
1627 switch (AUDIODEV(dev)) { 1718 switch (AUDIODEV(dev)) {
1628 case SOUND_DEVICE: 1719 case SOUND_DEVICE:
1629 case AUDIO_DEVICE: 1720 case AUDIO_DEVICE:
1630 error = audio_write(sc, uio, ioflag, file); 1721 error = audio_write(sc, uio, ioflag, file);
1631 break; 1722 break;
1632 case AUDIOCTL_DEVICE: 1723 case AUDIOCTL_DEVICE:
1633 case MIXER_DEVICE: 1724 case MIXER_DEVICE:
1634 error = ENODEV; 1725 error = ENODEV;
1635 break; 1726 break;
1636 default: 1727 default:
1637 error = ENXIO; 1728 error = ENXIO;
1638 break; 1729 break;
1639 } 1730 }
1640 1731
 1732 audio_file_exit(sc, &sc_ref);
1641 return error; 1733 return error;
1642} 1734}
1643 1735
1644static int 1736static int
1645audioioctl(struct file *fp, u_long cmd, void *addr) 1737audioioctl(struct file *fp, u_long cmd, void *addr)
1646{ 1738{
1647 struct audio_softc *sc; 1739 struct audio_softc *sc;
 1740 struct psref sc_ref;
1648 audio_file_t *file; 1741 audio_file_t *file;
1649 struct lwp *l = curlwp; 1742 struct lwp *l = curlwp;
1650 int error; 1743 int error;
1651 dev_t dev; 1744 dev_t dev;
1652 1745
1653 KASSERT(fp->f_audioctx); 1746 KASSERT(fp->f_audioctx);
1654 file = fp->f_audioctx; 1747 file = fp->f_audioctx;
1655 sc = file->sc; 
1656 dev = file->dev; 1748 dev = file->dev;
1657 1749
 1750 sc = audio_file_enter(file, &sc_ref);
 1751 if (sc == NULL)
 1752 return EIO;
 1753
1658 switch (AUDIODEV(dev)) { 1754 switch (AUDIODEV(dev)) {
1659 case SOUND_DEVICE: 1755 case SOUND_DEVICE:
1660 case AUDIO_DEVICE: 1756 case AUDIO_DEVICE:
1661 case AUDIOCTL_DEVICE: 1757 case AUDIOCTL_DEVICE:
1662 mutex_enter(sc->sc_lock); 1758 mutex_enter(sc->sc_lock);
1663 device_active(sc->sc_dev, DVA_SYSTEM); 1759 device_active(sc->sc_dev, DVA_SYSTEM);
1664 mutex_exit(sc->sc_lock); 1760 mutex_exit(sc->sc_lock);
1665 if (IOCGROUP(cmd) == IOCGROUP(AUDIO_MIXER_READ)) 1761 if (IOCGROUP(cmd) == IOCGROUP(AUDIO_MIXER_READ))
1666 error = mixer_ioctl(sc, cmd, addr, fp->f_flag, l); 1762 error = mixer_ioctl(sc, cmd, addr, fp->f_flag, l);
1667 else 1763 else
1668 error = audio_ioctl(dev, sc, cmd, addr, fp->f_flag, l, 1764 error = audio_ioctl(dev, sc, cmd, addr, fp->f_flag, l,
1669 file); 1765 file);
1670 break; 1766 break;
1671 case MIXER_DEVICE: 1767 case MIXER_DEVICE:
1672 error = mixer_ioctl(sc, cmd, addr, fp->f_flag, l); 1768 error = mixer_ioctl(sc, cmd, addr, fp->f_flag, l);
1673 break; 1769 break;
1674 default: 1770 default:
1675 error = ENXIO; 1771 error = ENXIO;
1676 break; 1772 break;
1677 } 1773 }
1678 1774
 1775 audio_file_exit(sc, &sc_ref);
1679 return error; 1776 return error;
1680} 1777}
1681 1778
1682static int 1779static int
1683audiostat(struct file *fp, struct stat *st) 1780audiostat(struct file *fp, struct stat *st)
1684{ 1781{
 1782 struct audio_softc *sc;
 1783 struct psref sc_ref;
1685 audio_file_t *file; 1784 audio_file_t *file;
1686 1785
1687 KASSERT(fp->f_audioctx); 1786 KASSERT(fp->f_audioctx);
1688 file = fp->f_audioctx; 1787 file = fp->f_audioctx;
1689 1788
 1789 sc = audio_file_enter(file, &sc_ref);
 1790 if (sc == NULL)
 1791 return EIO;
 1792
1690 memset(st, 0, sizeof(*st)); 1793 memset(st, 0, sizeof(*st));
1691 1794
1692 st->st_dev = file->dev; 1795 st->st_dev = file->dev;
1693 st->st_uid = kauth_cred_geteuid(fp->f_cred); 1796 st->st_uid = kauth_cred_geteuid(fp->f_cred);
1694 st->st_gid = kauth_cred_getegid(fp->f_cred); 1797 st->st_gid = kauth_cred_getegid(fp->f_cred);
1695 st->st_mode = S_IFCHR; 1798 st->st_mode = S_IFCHR;
 1799
 1800 audio_file_exit(sc, &sc_ref);
1696 return 0; 1801 return 0;
1697} 1802}
1698 1803
1699static int 1804static int
1700audiopoll(struct file *fp, int events) 1805audiopoll(struct file *fp, int events)
1701{ 1806{
1702 struct audio_softc *sc; 1807 struct audio_softc *sc;
 1808 struct psref sc_ref;
1703 audio_file_t *file; 1809 audio_file_t *file;
1704 struct lwp *l = curlwp; 1810 struct lwp *l = curlwp;
1705 int revents; 1811 int revents;
1706 dev_t dev; 1812 dev_t dev;
1707 1813
1708 KASSERT(fp->f_audioctx); 1814 KASSERT(fp->f_audioctx);
1709 file = fp->f_audioctx; 1815 file = fp->f_audioctx;
1710 sc = file->sc; 
1711 dev = file->dev; 1816 dev = file->dev;
1712 1817
 1818 sc = audio_file_enter(file, &sc_ref);
 1819 if (sc == NULL)
 1820 return EIO;
 1821
1713 switch (AUDIODEV(dev)) { 1822 switch (AUDIODEV(dev)) {
1714 case SOUND_DEVICE: 1823 case SOUND_DEVICE:
1715 case AUDIO_DEVICE: 1824 case AUDIO_DEVICE:
1716 revents = audio_poll(sc, events, l, file); 1825 revents = audio_poll(sc, events, l, file);
1717 break; 1826 break;
1718 case AUDIOCTL_DEVICE: 1827 case AUDIOCTL_DEVICE:
1719 case MIXER_DEVICE: 1828 case MIXER_DEVICE:
1720 revents = 0; 1829 revents = 0;
1721 break; 1830 break;
1722 default: 1831 default:
1723 revents = POLLERR; 1832 revents = POLLERR;
1724 break; 1833 break;
1725 } 1834 }
1726 1835
 1836 audio_file_exit(sc, &sc_ref);
1727 return revents; 1837 return revents;
1728} 1838}
1729 1839
1730static int 1840static int
1731audiokqfilter(struct file *fp, struct knote *kn) 1841audiokqfilter(struct file *fp, struct knote *kn)
1732{ 1842{
1733 struct audio_softc *sc; 1843 struct audio_softc *sc;
 1844 struct psref sc_ref;
1734 audio_file_t *file; 1845 audio_file_t *file;
1735 dev_t dev; 1846 dev_t dev;
1736 int error; 1847 int error;
1737 1848
1738 KASSERT(fp->f_audioctx); 1849 KASSERT(fp->f_audioctx);
1739 file = fp->f_audioctx; 1850 file = fp->f_audioctx;
1740 sc = file->sc; 
1741 dev = file->dev; 1851 dev = file->dev;
1742 1852
 1853 sc = audio_file_enter(file, &sc_ref);
 1854 if (sc == NULL)
 1855 return EIO;
 1856
1743 switch (AUDIODEV(dev)) { 1857 switch (AUDIODEV(dev)) {
1744 case SOUND_DEVICE: 1858 case SOUND_DEVICE:
1745 case AUDIO_DEVICE: 1859 case AUDIO_DEVICE:
1746 error = audio_kqfilter(sc, file, kn); 1860 error = audio_kqfilter(sc, file, kn);
1747 break; 1861 break;
1748 case AUDIOCTL_DEVICE: 1862 case AUDIOCTL_DEVICE:
1749 case MIXER_DEVICE: 1863 case MIXER_DEVICE:
1750 error = ENODEV; 1864 error = ENODEV;
1751 break; 1865 break;
1752 default: 1866 default:
1753 error = ENXIO; 1867 error = ENXIO;
1754 break; 1868 break;
1755 } 1869 }
1756 1870
 1871 audio_file_exit(sc, &sc_ref);
1757 return error; 1872 return error;
1758} 1873}
1759 1874
1760static int 1875static int
1761audiommap(struct file *fp, off_t *offp, size_t len, int prot, int *flagsp, 1876audiommap(struct file *fp, off_t *offp, size_t len, int prot, int *flagsp,
1762 int *advicep, struct uvm_object **uobjp, int *maxprotp) 1877 int *advicep, struct uvm_object **uobjp, int *maxprotp)
1763{ 1878{
1764 struct audio_softc *sc; 1879 struct audio_softc *sc;
 1880 struct psref sc_ref;
1765 audio_file_t *file; 1881 audio_file_t *file;
1766 dev_t dev; 1882 dev_t dev;
1767 int error; 1883 int error;
1768 1884
1769 KASSERT(fp->f_audioctx); 1885 KASSERT(fp->f_audioctx);
1770 file = fp->f_audioctx; 1886 file = fp->f_audioctx;
1771 sc = file->sc; 
1772 dev = file->dev; 1887 dev = file->dev;
1773 1888
 1889 sc = audio_file_enter(file, &sc_ref);
 1890 if (sc == NULL)
 1891 return EIO;
 1892
1774 mutex_enter(sc->sc_lock); 1893 mutex_enter(sc->sc_lock);
1775 device_active(sc->sc_dev, DVA_SYSTEM); /* XXXJDM */ 1894 device_active(sc->sc_dev, DVA_SYSTEM); /* XXXJDM */
1776 mutex_exit(sc->sc_lock); 1895 mutex_exit(sc->sc_lock);
1777 1896
1778 switch (AUDIODEV(dev)) { 1897 switch (AUDIODEV(dev)) {
1779 case SOUND_DEVICE: 1898 case SOUND_DEVICE:
1780 case AUDIO_DEVICE: 1899 case AUDIO_DEVICE:
1781 error = audio_mmap(sc, offp, len, prot, flagsp, advicep, 1900 error = audio_mmap(sc, offp, len, prot, flagsp, advicep,
1782 uobjp, maxprotp, file); 1901 uobjp, maxprotp, file);
1783 break; 1902 break;
1784 case AUDIOCTL_DEVICE: 1903 case AUDIOCTL_DEVICE:
1785 case MIXER_DEVICE: 1904 case MIXER_DEVICE:
1786 default: 1905 default:
1787 error = ENOTSUP; 1906 error = ENOTSUP;
1788 break; 1907 break;
1789 } 1908 }
1790 1909
 1910 audio_file_exit(sc, &sc_ref);
1791 return error; 1911 return error;
1792} 1912}
1793 1913
1794 1914
1795/* Exported interfaces for audiobell. */ 1915/* Exported interfaces for audiobell. */
1796 1916
1797/* 1917/*
1798 * Open for audiobell. 1918 * Open for audiobell.
1799 * It stores allocated file to *filep. 1919 * It stores allocated file to *filep.
1800 * If successful returns 0, otherwise errno. 1920 * If successful returns 0, otherwise errno.
1801 */ 1921 */
1802int 1922int
1803audiobellopen(dev_t dev, audio_file_t **filep) 1923audiobellopen(dev_t dev, audio_file_t **filep)
@@ -1816,67 +1936,81 @@ audiobellopen(dev_t dev, audio_file_t ** @@ -1816,67 +1936,81 @@ audiobellopen(dev_t dev, audio_file_t **
1816 1936
1817 device_active(sc->sc_dev, DVA_SYSTEM); 1937 device_active(sc->sc_dev, DVA_SYSTEM);
1818 error = audio_open(dev, sc, FWRITE, 0, curlwp, filep); 1938 error = audio_open(dev, sc, FWRITE, 0, curlwp, filep);
1819 1939
1820 audio_exit_exclusive(sc); 1940 audio_exit_exclusive(sc);
1821 return error; 1941 return error;
1822} 1942}
1823 1943
1824/* Close for audiobell */ 1944/* Close for audiobell */
1825int 1945int
1826audiobellclose(audio_file_t *file) 1946audiobellclose(audio_file_t *file)
1827{ 1947{
1828 struct audio_softc *sc; 1948 struct audio_softc *sc;
 1949 struct psref sc_ref;
1829 int error; 1950 int error;
1830 1951
1831 sc = file->sc; 1952 sc = audio_file_enter(file, &sc_ref);
 1953 if (sc == NULL)
 1954 return EIO;
1832 1955
1833 device_active(sc->sc_dev, DVA_SYSTEM); 
1834 error = audio_close(sc, file); 1956 error = audio_close(sc, file);
1835 1957
 1958 audio_file_exit(sc, &sc_ref);
1836 return error; 1959 return error;
1837} 1960}
1838 1961
1839/* Set sample rate for audiobell */ 1962/* Set sample rate for audiobell */
1840int 1963int
1841audiobellsetrate(audio_file_t *file, u_int sample_rate) 1964audiobellsetrate(audio_file_t *file, u_int sample_rate)
1842{ 1965{
1843 struct audio_softc *sc; 1966 struct audio_softc *sc;
 1967 struct psref sc_ref;
1844 struct audio_info ai; 1968 struct audio_info ai;
1845 int error; 1969 int error;
1846 1970
1847 sc = file->sc; 1971 sc = audio_file_enter(file, &sc_ref);
 1972 if (sc == NULL)
 1973 return EIO;
1848 1974
1849 AUDIO_INITINFO(&ai); 1975 AUDIO_INITINFO(&ai);
1850 ai.play.sample_rate = sample_rate; 1976 ai.play.sample_rate = sample_rate;
1851 1977
1852 error = audio_enter_exclusive(sc); 1978 error = audio_enter_exclusive(sc);
1853 if (error) 1979 if (error)
1854 return error; 1980 goto done;
1855 error = audio_file_setinfo(sc, file, &ai); 1981 error = audio_file_setinfo(sc, file, &ai);
1856 audio_exit_exclusive(sc); 1982 audio_exit_exclusive(sc);
1857 1983
 1984done:
 1985 audio_file_exit(sc, &sc_ref);
1858 return error; 1986 return error;
1859} 1987}
1860 1988
1861/* Playback for audiobell */ 1989/* Playback for audiobell */
1862int 1990int
1863audiobellwrite(audio_file_t *file, struct uio *uio) 1991audiobellwrite(audio_file_t *file, struct uio *uio)
1864{ 1992{
1865 struct audio_softc *sc; 1993 struct audio_softc *sc;
 1994 struct psref sc_ref;
1866 int error; 1995 int error;
1867 1996
1868 sc = file->sc; 1997 sc = audio_file_enter(file, &sc_ref);
 1998 if (sc == NULL)
 1999 return EIO;
 2000
1869 error = audio_write(sc, uio, 0, file); 2001 error = audio_write(sc, uio, 0, file);
 2002
 2003 audio_file_exit(sc, &sc_ref);
1870 return error; 2004 return error;
1871} 2005}
1872 2006
1873 2007
1874/* 2008/*
1875 * Audio driver 2009 * Audio driver
1876 */ 2010 */
1877int 2011int
1878audio_open(dev_t dev, struct audio_softc *sc, int flags, int ifmt, 2012audio_open(dev_t dev, struct audio_softc *sc, int flags, int ifmt,
1879 struct lwp *l, audio_file_t **bellfile) 2013 struct lwp *l, audio_file_t **bellfile)
1880{ 2014{
1881 struct audio_info ai; 2015 struct audio_info ai;
1882 struct file *fp; 2016 struct file *fp;
@@ -2121,126 +2255,144 @@ bad2: @@ -2121,126 +2255,144 @@ bad2:
2121 af->ptrack = NULL; 2255 af->ptrack = NULL;
2122 } 2256 }
2123bad1: 2257bad1:
2124 kmem_free(af, sizeof(*af)); 2258 kmem_free(af, sizeof(*af));
2125 return error; 2259 return error;
2126} 2260}
2127 2261
2128/* 2262/*
2129 * Must be called without sc_lock nor sc_exlock held. 2263 * Must be called without sc_lock nor sc_exlock held.
2130 */ 2264 */
2131int 2265int
2132audio_close(struct audio_softc *sc, audio_file_t *file) 2266audio_close(struct audio_softc *sc, audio_file_t *file)
2133{ 2267{
2134 audio_track_t *oldtrack; 2268
 2269 /* Protect entering new fileops to this file */
 2270 atomic_store_relaxed(&file->dying, true);
 2271
 2272 /*
 2273 * Drain first.
 2274 * It must be done before unlinking(acquiring exclusive lock).
 2275 */
 2276 if (file->ptrack) {
 2277 mutex_enter(sc->sc_lock);
 2278 audio_track_drain(sc, file->ptrack);
 2279 mutex_exit(sc->sc_lock);
 2280 }
 2281
 2282 return audio_unlink(sc, file);
 2283}
 2284
 2285/*
 2286 * Unlink this file, but not freeing memory here.
 2287 * Must be called without sc_lock nor sc_exlock held.
 2288 */
 2289int
 2290audio_unlink(struct audio_softc *sc, audio_file_t *file)
 2291{
2135 int error; 2292 int error;
2136 2293
2137 TRACEF(1, file, "%spid=%d.%d po=%d ro=%d", 2294 TRACEF(1, file, "%spid=%d.%d po=%d ro=%d",
2138 (audiodebug >= 3) ? "start " : "", 2295 (audiodebug >= 3) ? "start " : "",
2139 (int)curproc->p_pid, (int)curlwp->l_lid, 2296 (int)curproc->p_pid, (int)curlwp->l_lid,
2140 sc->sc_popens, sc->sc_ropens); 2297 sc->sc_popens, sc->sc_ropens);
2141 KASSERTMSG(sc->sc_popens + sc->sc_ropens > 0, 2298 KASSERTMSG(sc->sc_popens + sc->sc_ropens > 0,
2142 "sc->sc_popens=%d, sc->sc_ropens=%d", 2299 "sc->sc_popens=%d, sc->sc_ropens=%d",
2143 sc->sc_popens, sc->sc_ropens); 2300 sc->sc_popens, sc->sc_ropens);
2144 2301
 2302 mutex_enter(sc->sc_lock);
2145 /* 2303 /*
2146 * Drain first. 2304 * Acquire exclusive lock to protect counters.
2147 * It must be done before acquiring exclusive lock. 2305 * Does not use audio_enter_exclusive() due to sc_dying.
2148 */ 2306 */
2149 if (file->ptrack) { 2307 while (__predict_false(sc->sc_exlock != 0)) {
2150 mutex_enter(sc->sc_lock); 2308 error = cv_timedwait_sig(&sc->sc_exlockcv, sc->sc_lock,
2151 audio_track_drain(sc, file->ptrack); 2309 mstohz(AUDIO_TIMEOUT));
2152 mutex_exit(sc->sc_lock); 2310 /* XXX what should I do on error? */
 2311 if (error == EWOULDBLOCK) {
 2312 mutex_exit(sc->sc_lock);
 2313 device_printf(sc->sc_dev,
 2314 "%s: cv_timedwait_sig failed %d", __func__, error);
 2315 return error;
 2316 }
2153 } 2317 }
 2318 sc->sc_exlock = 1;
2154 2319
2155 /* Then, acquire exclusive lock to protect counters. */ 2320 device_active(sc->sc_dev, DVA_SYSTEM);
2156 /* XXX what should I do when an error occurs? */ 2321
2157 error = audio_enter_exclusive(sc); 2322 mutex_enter(sc->sc_intr_lock);
2158 if (error) 2323 SLIST_REMOVE(&sc->sc_files, file, audio_file, entry);
2159 return error; 2324 mutex_exit(sc->sc_intr_lock);
2160 2325
2161 if (file->ptrack) { 2326 if (file->ptrack) {
 2327 TRACET(3, file->ptrack, "dropframes=%" PRIu64,
 2328 file->ptrack->dropframes);
 2329
 2330 KASSERT(sc->sc_popens > 0);
 2331 sc->sc_popens--;
 2332
2162 /* Call hw halt_output if this is the last playback track. */ 2333 /* Call hw halt_output if this is the last playback track. */
2163 if (sc->sc_popens == 1 && sc->sc_pbusy) { 2334 if (sc->sc_popens == 0 && sc->sc_pbusy) {
2164 error = audio_pmixer_halt(sc); 2335 error = audio_pmixer_halt(sc);
2165 if (error) { 2336 if (error) {
2166 device_printf(sc->sc_dev, 2337 device_printf(sc->sc_dev,
2167 "halt_output failed with %d\n", error); 2338 "halt_output failed with %d (ignored)\n",
 2339 error);
2168 } 2340 }
2169 } 2341 }
2170 2342
2171 /* Destroy the track. */ 
2172 oldtrack = file->ptrack; 
2173 mutex_enter(sc->sc_intr_lock); 
2174 file->ptrack = NULL; 
2175 mutex_exit(sc->sc_intr_lock); 
2176 TRACET(3, oldtrack, "dropframes=%" PRIu64, 
2177 oldtrack->dropframes); 
2178 audio_track_destroy(oldtrack); 
2179 
2180 KASSERT(sc->sc_popens > 0); 
2181 sc->sc_popens--; 
2182 
2183 /* Restore mixing volume if all tracks are gone. */ 2343 /* Restore mixing volume if all tracks are gone. */
2184 if (sc->sc_popens == 0) { 2344 if (sc->sc_popens == 0) {
 2345 /* intr_lock is not necessary, but just manners. */
2185 mutex_enter(sc->sc_intr_lock); 2346 mutex_enter(sc->sc_intr_lock);
2186 sc->sc_pmixer->volume = 256; 2347 sc->sc_pmixer->volume = 256;
2187 sc->sc_pmixer->voltimer = 0; 2348 sc->sc_pmixer->voltimer = 0;
2188 mutex_exit(sc->sc_intr_lock); 2349 mutex_exit(sc->sc_intr_lock);
2189 } 2350 }
2190 } 2351 }
2191 if (file->rtrack) { 2352 if (file->rtrack) {
 2353 TRACET(3, file->rtrack, "dropframes=%" PRIu64,
 2354 file->rtrack->dropframes);
 2355
 2356 KASSERT(sc->sc_ropens > 0);
 2357 sc->sc_ropens--;
 2358
2192 /* Call hw halt_input if this is the last recording track. */ 2359 /* Call hw halt_input if this is the last recording track. */
2193 if (sc->sc_ropens == 1 && sc->sc_rbusy) { 2360 if (sc->sc_ropens == 0 && sc->sc_rbusy) {
2194 error = audio_rmixer_halt(sc); 2361 error = audio_rmixer_halt(sc);
2195 if (error) { 2362 if (error) {
2196 device_printf(sc->sc_dev, 2363 device_printf(sc->sc_dev,
2197 "halt_input failed with %d\n", error); 2364 "halt_input failed with %d (ignored)\n",
 2365 error);
2198 } 2366 }
2199 } 2367 }
2200 2368
2201 /* Destroy the track. */ 
2202 oldtrack = file->rtrack; 
2203 mutex_enter(sc->sc_intr_lock); 
2204 file->rtrack = NULL; 
2205 mutex_exit(sc->sc_intr_lock); 
2206 TRACET(3, oldtrack, "dropframes=%" PRIu64, 
2207 oldtrack->dropframes); 
2208 audio_track_destroy(oldtrack); 
2209 
2210 KASSERT(sc->sc_ropens > 0); 
2211 sc->sc_ropens--; 
2212 } 2369 }
2213 2370
2214 /* Call hw close if this is the last track. */ 2371 /* Call hw close if this is the last track. */
2215 if (sc->sc_popens + sc->sc_ropens == 0) { 2372 if (sc->sc_popens + sc->sc_ropens == 0) {
2216 if (sc->hw_if->close) { 2373 if (sc->hw_if->close) {
2217 TRACE(2, "hw_if close"); 2374 TRACE(2, "hw_if close");
2218 mutex_enter(sc->sc_intr_lock); 2375 mutex_enter(sc->sc_intr_lock);
2219 sc->hw_if->close(sc->hw_hdl); 2376 sc->hw_if->close(sc->hw_hdl);
2220 mutex_exit(sc->sc_intr_lock); 2377 mutex_exit(sc->sc_intr_lock);
2221 } 2378 }
2222 2379
2223 kauth_cred_free(sc->sc_cred); 2380 kauth_cred_free(sc->sc_cred);
2224 } 2381 }
2225 2382
2226 mutex_enter(sc->sc_intr_lock); 
2227 SLIST_REMOVE(&sc->sc_files, file, audio_file, entry); 
2228 mutex_exit(sc->sc_intr_lock); 
2229 
2230 TRACE(3, "done"); 2383 TRACE(3, "done");
2231 audio_exit_exclusive(sc); 2384 audio_exit_exclusive(sc);
2232 2385
2233 kmem_free(file, sizeof(*file)); 
2234 return 0; 2386 return 0;
2235} 2387}
2236 2388
2237/* 2389/*
2238 * Must be called without sc_lock nor sc_exlock held. 2390 * Must be called without sc_lock nor sc_exlock held.
2239 */ 2391 */
2240int 2392int
2241audio_read(struct audio_softc *sc, struct uio *uio, int ioflag, 2393audio_read(struct audio_softc *sc, struct uio *uio, int ioflag,
2242 audio_file_t *file) 2394 audio_file_t *file)
2243{ 2395{
2244 audio_track_t *track; 2396 audio_track_t *track;
2245 audio_ring_t *usrbuf; 2397 audio_ring_t *usrbuf;
2246 audio_ring_t *input; 2398 audio_ring_t *input;
@@ -3082,34 +3234,26 @@ audioctl_open(dev_t dev, struct audio_so @@ -3082,34 +3234,26 @@ audioctl_open(dev_t dev, struct audio_so
3082 3234
3083 af = kmem_zalloc(sizeof(audio_file_t), KM_SLEEP); 3235 af = kmem_zalloc(sizeof(audio_file_t), KM_SLEEP);
3084 af->sc = sc; 3236 af->sc = sc;
3085 af->dev = dev; 3237 af->dev = dev;
3086 3238
3087 /* Not necessary to insert sc_files. */ 3239 /* Not necessary to insert sc_files. */
3088 3240
3089 error = fd_clone(fp, fd, flags, &audio_fileops, af); 3241 error = fd_clone(fp, fd, flags, &audio_fileops, af);
3090 KASSERTMSG(error == EMOVEFD, "error=%d", error); 3242 KASSERTMSG(error == EMOVEFD, "error=%d", error);
3091 3243
3092 return error; 3244 return error;
3093} 3245}
3094 3246
3095static int 
3096audioctl_close(struct audio_softc *sc, audio_file_t *file) 
3097{ 
3098 
3099 kmem_free(file, sizeof(*file)); 
3100 return 0; 
3101} 
3102 
3103/* 3247/*
3104 * Free 'mem' if available, and initialize the pointer. 3248 * Free 'mem' if available, and initialize the pointer.
3105 * For this reason, this is implemented as macro. 3249 * For this reason, this is implemented as macro.
3106 */ 3250 */
3107#define audio_free(mem) do { \ 3251#define audio_free(mem) do { \
3108 if (mem != NULL) { \ 3252 if (mem != NULL) { \
3109 kern_free(mem); \ 3253 kern_free(mem); \
3110 mem = NULL; \ 3254 mem = NULL; \
3111 } \ 3255 } \
3112} while (0) 3256} while (0)
3113 3257
3114/* 3258/*
3115 * (Re)allocate 'memblock' with specified 'bytes'. 3259 * (Re)allocate 'memblock' with specified 'bytes'.
@@ -7683,27 +7827,26 @@ mixer_signal(struct audio_softc *sc) @@ -7683,27 +7827,26 @@ mixer_signal(struct audio_softc *sc)
7683 7827
7684/* 7828/*
7685 * Close a mixer device 7829 * Close a mixer device
7686 */ 7830 */
7687int 7831int
7688mixer_close(struct audio_softc *sc, audio_file_t *file) 7832mixer_close(struct audio_softc *sc, audio_file_t *file)
7689{ 7833{
7690 7834
7691 mutex_enter(sc->sc_lock); 7835 mutex_enter(sc->sc_lock);
7692 TRACE(1, ""); 7836 TRACE(1, "");
7693 mixer_async_remove(sc, curproc->p_pid); 7837 mixer_async_remove(sc, curproc->p_pid);
7694 mutex_exit(sc->sc_lock); 7838 mutex_exit(sc->sc_lock);
7695 7839
7696 kmem_free(file, sizeof(*file)); 
7697 return 0; 7840 return 0;
7698} 7841}
7699 7842
7700/* 7843/*
7701 * Must be called without sc_lock nor sc_exlock held. 7844 * Must be called without sc_lock nor sc_exlock held.
7702 */ 7845 */
7703int 7846int
7704mixer_ioctl(struct audio_softc *sc, u_long cmd, void *addr, int flag, 7847mixer_ioctl(struct audio_softc *sc, u_long cmd, void *addr, int flag,
7705 struct lwp *l) 7848 struct lwp *l)
7706{ 7849{
7707 mixer_devinfo_t *mi; 7850 mixer_devinfo_t *mi;
7708 mixer_ctrl_t *mc; 7851 mixer_ctrl_t *mc;
7709 int error; 7852 int error;
@@ -8435,43 +8578,48 @@ audioprint(void *aux, const char *pnp) @@ -8435,43 +8578,48 @@ audioprint(void *aux, const char *pnp)
8435devmajor_t audio_bmajor = -1, audio_cmajor = -1; 8578devmajor_t audio_bmajor = -1, audio_cmajor = -1;
8436 8579
8437#include "ioconf.c" 8580#include "ioconf.c"
8438 8581
8439#endif 8582#endif
8440 8583
8441MODULE(MODULE_CLASS_DRIVER, audio, NULL); 8584MODULE(MODULE_CLASS_DRIVER, audio, NULL);
8442 8585
8443static int 8586static int
8444audio_modcmd(modcmd_t cmd, void *arg) 8587audio_modcmd(modcmd_t cmd, void *arg)
8445{ 8588{
8446 int error = 0; 8589 int error = 0;
8447 8590
8448#ifdef _MODULE 
8449 switch (cmd) { 8591 switch (cmd) {
8450 case MODULE_CMD_INIT: 8592 case MODULE_CMD_INIT:
 8593 /* XXX interrupt level? */
 8594 audio_psref_class = psref_class_create("audio", IPL_SOFTSERIAL);
 8595#ifdef _MODULE
8451 error = devsw_attach(audio_cd.cd_name, NULL, &audio_bmajor, 8596 error = devsw_attach(audio_cd.cd_name, NULL, &audio_bmajor,
8452 &audio_cdevsw, &audio_cmajor); 8597 &audio_cdevsw, &audio_cmajor);
8453 if (error) 8598 if (error)
8454 break; 8599 break;
8455 8600
8456 error = config_init_component(cfdriver_ioconf_audio, 8601 error = config_init_component(cfdriver_ioconf_audio,
8457 cfattach_ioconf_audio, cfdata_ioconf_audio); 8602 cfattach_ioconf_audio, cfdata_ioconf_audio);
8458 if (error) { 8603 if (error) {
8459 devsw_detach(NULL, &audio_cdevsw); 8604 devsw_detach(NULL, &audio_cdevsw);
8460 } 8605 }
 8606#endif
8461 break; 8607 break;
8462 case MODULE_CMD_FINI: 8608 case MODULE_CMD_FINI:
 8609#ifdef _MODULE
8463 devsw_detach(NULL, &audio_cdevsw); 8610 devsw_detach(NULL, &audio_cdevsw);
8464 error = config_fini_component(cfdriver_ioconf_audio, 8611 error = config_fini_component(cfdriver_ioconf_audio,
8465 cfattach_ioconf_audio, cfdata_ioconf_audio); 8612 cfattach_ioconf_audio, cfdata_ioconf_audio);
8466 if (error) 8613 if (error)
8467 devsw_attach(audio_cd.cd_name, NULL, &audio_bmajor, 8614 devsw_attach(audio_cd.cd_name, NULL, &audio_bmajor,
8468 &audio_cdevsw, &audio_cmajor); 8615 &audio_cdevsw, &audio_cmajor);
 8616#endif
 8617 psref_class_destroy(audio_psref_class);
8469 break; 8618 break;
8470 default: 8619 default:
8471 error = ENOTTY; 8620 error = ENOTTY;
8472 break; 8621 break;
8473 } 8622 }
8474#endif 
8475 8623
8476 return error; 8624 return error;
8477} 8625}

cvs diff -r1.9 -r1.10 src/sys/dev/audio/audiodef.h (expand / switch to unified diff)

--- src/sys/dev/audio/audiodef.h 2020/02/22 06:58:39 1.9
+++ src/sys/dev/audio/audiodef.h 2020/02/23 07:17:01 1.10
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: audiodef.h,v 1.9 2020/02/22 06:58:39 isaki Exp $ */ 1/* $NetBSD: audiodef.h,v 1.10 2020/02/23 07:17:01 isaki Exp $ */
2 2
3/* 3/*
4 * Copyright (C) 2017 Tetsuya Isaki. All rights reserved. 4 * Copyright (C) 2017 Tetsuya Isaki. All rights reserved.
5 * Copyright (C) 2017 Y.Sugahara (moveccr). All rights reserved. 5 * Copyright (C) 2017 Y.Sugahara (moveccr). All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -192,26 +192,29 @@ struct audio_file { @@ -192,26 +192,29 @@ struct audio_file {
192 192
193 /* 193 /*
194 * Indicates the operation mode of this file. 194 * Indicates the operation mode of this file.
195 * AUMODE_PLAY means playback is requested. 195 * AUMODE_PLAY means playback is requested.
196 * AUMODE_RECORD means recording is requested. 196 * AUMODE_RECORD means recording is requested.
197 * AUMODE_PLAY_ALL affects nothing but can be get/set for backward 197 * AUMODE_PLAY_ALL affects nothing but can be get/set for backward
198 * compatibility. 198 * compatibility.
199 */ 199 */
200 int mode; 200 int mode;
201 201
202 /* process who wants audio SIGIO. */ 202 /* process who wants audio SIGIO. */
203 pid_t async_audio; 203 pid_t async_audio;
204 204
 205 /* true when closing */
 206 bool dying;
 207
205 SLIST_ENTRY(audio_file) entry; 208 SLIST_ENTRY(audio_file) entry;
206}; 209};
207 210
208struct audio_trackmixer { 211struct audio_trackmixer {
209 struct audio_softc *sc; 212 struct audio_softc *sc;
210 213
211 int mode; /* AUMODE_PLAY or AUMODE_RECORD */ 214 int mode; /* AUMODE_PLAY or AUMODE_RECORD */
212 audio_format2_t track_fmt; /* track <-> trackmixer format */ 215 audio_format2_t track_fmt; /* track <-> trackmixer format */
213 216
214 int frames_per_block; /* number of frames in a block */ 217 int frames_per_block; /* number of frames in a block */
215 218
216 /* 219 /*
217 * software master volume (0..256) 220 * software master volume (0..256)

cvs diff -r1.7 -r1.8 src/sys/dev/audio/audiovar.h (expand / switch to unified diff)

--- src/sys/dev/audio/audiovar.h 2020/01/11 04:53:10 1.7
+++ src/sys/dev/audio/audiovar.h 2020/02/23 07:17:01 1.8
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: audiovar.h,v 1.7 2020/01/11 04:53:10 isaki Exp $ */ 1/* $NetBSD: audiovar.h,v 1.8 2020/02/23 07:17:01 isaki Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2002 The NetBSD Foundation, Inc. 4 * Copyright (c) 2002 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by TAMURA Kent 8 * by TAMURA Kent
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -59,26 +59,28 @@ @@ -59,26 +59,28 @@
59 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 59 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
60 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 60 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
61 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 61 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
62 * SUCH DAMAGE. 62 * SUCH DAMAGE.
63 * 63 *
64 * From: Header: audiovar.h,v 1.3 93/07/18 14:07:25 mccanne Exp (LBL) 64 * From: Header: audiovar.h,v 1.3 93/07/18 14:07:25 mccanne Exp (LBL)
65 */ 65 */
66 66
67#ifndef _SYS_DEV_AUDIO_AUDIOVAR_H_ 67#ifndef _SYS_DEV_AUDIO_AUDIOVAR_H_
68#define _SYS_DEV_AUDIO_AUDIOVAR_H_ 68#define _SYS_DEV_AUDIO_AUDIOVAR_H_
69 69
70#include <sys/condvar.h> 70#include <sys/condvar.h>
71#include <sys/proc.h> 71#include <sys/proc.h>
 72#include <sys/pserialize.h>
 73#include <sys/psref.h>
72#include <sys/queue.h> 74#include <sys/queue.h>
73 75
74#include <dev/audio/audio_if.h> 76#include <dev/audio/audio_if.h>
75#include <dev/audio/audiofil.h> 77#include <dev/audio/audiofil.h>
76 78
77/* 79/*
78 * Whether supports [US]LINEAR24/24 as userland format. 80 * Whether supports [US]LINEAR24/24 as userland format.
79 */ 81 */
80/* #define AUDIO_SUPPORT_LINEAR24 */ 82/* #define AUDIO_SUPPORT_LINEAR24 */
81 83
82/* 84/*
83 * Frequency range. 85 * Frequency range.
84 * For lower limit, there are some antique machines who supports under 86 * For lower limit, there are some antique machines who supports under
@@ -208,26 +210,33 @@ struct audio_softc { @@ -208,26 +210,33 @@ struct audio_softc {
208 * Thread lock and interrupt lock obtained by get_locks(). 210 * Thread lock and interrupt lock obtained by get_locks().
209 */ 211 */
210 kmutex_t *sc_lock; 212 kmutex_t *sc_lock;
211 kmutex_t *sc_intr_lock; 213 kmutex_t *sc_intr_lock;
212 214
213 /* 215 /*
214 * Critical section. 216 * Critical section.
215 * Must be protected by sc_lock. 217 * Must be protected by sc_lock.
216 */ 218 */
217 int sc_exlock; 219 int sc_exlock;
218 kcondvar_t sc_exlockcv; 220 kcondvar_t sc_exlockcv;
219 221
220 /* 222 /*
 223 * Passive reference to prevent a race between detach and fileops.
 224 * pserialize_perform(sc_psz) must be protected by sc_lock.
 225 */
 226 pserialize_t sc_psz;
 227 struct psref_target sc_psref;
 228
 229 /*
221 * Must be protected by sc_lock (?) 230 * Must be protected by sc_lock (?)
222 */ 231 */
223 bool sc_dying; 232 bool sc_dying;
224 233
225 /* 234 /*
226 * If multiuser is false, other users who have different euid 235 * If multiuser is false, other users who have different euid
227 * than the first user cannot open this device. 236 * than the first user cannot open this device.
228 * Must be protected by sc_lock. 237 * Must be protected by sc_lock.
229 */ 238 */
230 bool sc_multiuser; 239 bool sc_multiuser;
231 kauth_cred_t sc_cred; 240 kauth_cred_t sc_cred;
232 241
233 struct sysctllog *sc_log; 242 struct sysctllog *sc_log;