Date: Tue, 4 Apr 2006 17:43:49 +0000 (UTC) From: Ariff Abdullah <ariff@FreeBSD.org> To: src-committers@FreeBSD.org, cvs-src@FreeBSD.org, cvs-all@FreeBSD.org Subject: cvs commit: src/sys/dev/sound/pcm dsp.c mixer.c sound.c sound.h vchan.c Message-ID: <200604041743.k34Hhnvd079702@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
ariff 2006-04-04 17:43:49 UTC FreeBSD src repository Modified files: (Branch: RELENG_6) sys/dev/sound/pcm dsp.c mixer.c sound.c sound.h vchan.c Log: MFC: dsp.c revision 1.95 mixer.c revision 1.49 sound.c revision 1.103 sound.h revision 1.68 vchan.c revision 1.24 MEGA Fixes / Cleanup -------------------- Fix severe 8bit integer overflow during channel creation and destruction, especially for vchans. It turns out that channel numbering always depend on d->devcount counter (which keep increasing), while PCMMKMINOR() truncate everything to 8bit length. At some point the truncation cause the newly created character device overlapped with the existed one, causing erratic overall system behaviour and panic. Easily reproduce with something like: (Luckily, only root can reproduce this) while : ; do sysctl hw.snd.pcm0.vchans=200 sysctl hw.snd.pcm0.vchans=100 done - Enforce channel/chardev numbering within 8bit boundary. Return E2BIG if necessary. - Traverse d->channels SLIST and try to reclaim "free" counter during channel creation. Don't rely on d->devcount at all. - Determine open direction using 'flags', not 'mode'. This bug exist since past 4 years. - Don't allow opening the same device twice, be it in a same or different direction. - O_RDWR is allowed, provided that it is done by a single open (for example by mixer(8)) and the underlying hardware support true full-duplex operation. - Seal the fate of long standing memory leak (4 years, 7 months) during pcm_unregister(). While destroying cdevs, scan / detect possible children and free its SLIST placeholder properly. - Optimize channel allocation / numbering even further. Do brute cyclic checking only if the channel numbering screwed. - Mega vchan create/destroy cleanup: o Implement pcm_setvchans() so everybody can use it freely instead of implementing their own, be it through sysctl or channel auto allocation. o Increase vchan creation/destruction resiliency: + it's possible to increase/decrease total vchans even during busy playback/recording. Busy channel will be left alone, untouched. Abusive test sample: # play whatever... # while : ; do sysctl hw.snd.pcm0.vchans=1 sysctl hw.snd.pcm0.vchans=10 sysctl hw.snd.pcm0.vchans=100 sysctl hw.snd.pcm0.vchans=200 done # Play something else, leave above loop running frantically. + Seal another 4 years old bug where it is possible to destroy (virtual) channel even when its cdevs being referenced by other process. The "First Come First Served" nature of dsp_clone() is the main culprit of this issue, and usually manifest itself as dangling channel <-> process association. Ensure that all of its cdevs are free from being referenced before destroying it (through ORPHAN_CDEVT() macross). Approved by: re (scottl) Revision Changes Path 1.80.2.6 +66 -90 src/sys/dev/sound/pcm/dsp.c 1.43.2.4 +13 -1 src/sys/dev/sound/pcm/mixer.c 1.93.2.3 +373 -303 src/sys/dev/sound/pcm/sound.c 1.63.2.2 +12 -7 src/sys/dev/sound/pcm/sound.h 1.17.2.4 +49 -33 src/sys/dev/sound/pcm/vchan.c
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200604041743.k34Hhnvd079702>