In D47932#1120121, @christos wrote:In D47932#1119492, @christos wrote:Declare as extern in header file and define as __always_inline. Not sure if
that give us the desired functionality yet.Apparently my comment following this never went through and I saw it now. But as is expected, the tests do not build if we define the functions like this.
- Queries
- All Stories
- Search
- Advanced Search
- Transactions
- Transaction Logs
Feed Advanced Search
Advanced Search
Advanced Search
Tue, Feb 25
Tue, Feb 25
Wed, Feb 19
Wed, Feb 19
In D47932#1118481, @markj wrote:In D47932#1118466, @dev_submerge.ch wrote:In D47932#1118261, @christos wrote:In D47932#1117964, @dev_submerge.ch wrote:In D47932#1117452, @christos wrote:Remove __always_inline. Related discussion in D47638.
Aren't we mixing up things here? Regarding performance, we definitely want __always_inline (or __attribute__((__always_inline__))) I suppose. The only issue with that is the unused warnings, which are fully legitimate because we define static functions that are unused in some translation units. There's other ways to fix that, and it seems strange to me that an additional __inline would prevent those warnings.
I also do not completely understand why the warnings go away with an additional __inline, to be honest. I trust @markj's judgement on this.
IIRC the additional __inline is what broke compilation with it being a duplicate declaration specifier. But instead of reverting that and fixing the original unused warnings, we're now relaxing the inline specifier to something which has a very compiler-specific and C version dependent interpretation.
My complaint about the original patch is that the __unused function is misleading, as the functions are not unused. It's very common for us to define static functions in header files, and they're virtually all defined __inline precisely to suppress warnings about unused functions, rather than out of any particular concern about controlling whether or not they do get inlined. So, yes, this is an abuse of the specifier, but all else being equal I'd rather handle that problem consistently within the tree.
Tue, Feb 18
Tue, Feb 18
In D47932#1118261, @christos wrote:In D47932#1117964, @dev_submerge.ch wrote:In D47932#1117452, @christos wrote:Remove __always_inline. Related discussion in D47638.
Aren't we mixing up things here? Regarding performance, we definitely want __always_inline (or __attribute__((__always_inline__))) I suppose. The only issue with that is the unused warnings, which are fully legitimate because we define static functions that are unused in some translation units. There's other ways to fix that, and it seems strange to me that an additional __inline would prevent those warnings.
I also do not completely understand why the warnings go away with an additional __inline, to be honest. I trust @markj's judgement on this.
Sun, Feb 16
Sun, Feb 16
In D47932#1117452, @christos wrote:Remove __always_inline. Related discussion in D47638.
Feb 11 2025
Feb 11 2025
dev_submerge.ch added inline comments to D48926: sound tests: Fix downshift calculation in pcm_read_write test.
dev_submerge.ch updated the diff for D48926: sound tests: Fix downshift calculation in pcm_read_write test.
Put braces around if block as suggested.
Feb 10 2025
Feb 10 2025
dev_submerge.ch requested review of D48926: sound tests: Fix downshift calculation in pcm_read_write test.
Feb 2 2025
Feb 2 2025
In D47638#1111768, @christos wrote:@dev_submerge.ch The big endian tests fail, because on a little endian machine,
converting 0x3f000000 (0.5) to 0x0000003f will result in the float value being
0, so the pcm_sample_* functions return will return wrong values. For
example, pcm_sample_read() reads the input as float (i.e 0x3f000000 ->
0.5), then converts it to big endian (0x3f000000 -> 0x0000003f -> 0), and
lastly converts it to S32 (0 * PCM_S32_MAX = 0), in which case the return
value will be 0, hence the test failure. I am not sure yet how we should adapt
the test program to accomodate floating-point big endian tests.
I have a proposal to simplify this code, may be worth considering. The general idea would be to
Jan 27 2025
Jan 27 2025
Jan 26 2025
Jan 26 2025
In D47932#1110250, @christos wrote:@dev_submerge.ch Both 32 and 64 bit tests pass normally (with the fix mentioned in D48330). Are we done with this one?
Jan 25 2025
Jan 25 2025
Reapprove.
Reapprove, I already accepted this.
Definitely better. The initial values of vchanformat and vchanrate are still off, but now they adopt the real channel parameters once set via sysctl. We can fix the initial values in a separate patch.
Jan 23 2025
Jan 23 2025
dev_submerge.ch added a comment to D48617: sound tests: Fix 32bit calculation detection in pcm_read_write.
To the best of my knowledge, this should fix the test on i386. I haven't spotted any other test failures yet on CI, but that's not conclusive - some architectures seem to have build failures and won't run the tests.
dev_submerge.ch requested review of D48617: sound tests: Fix 32bit calculation detection in pcm_read_write.
Jan 22 2025
Jan 22 2025
Ok, the CI builds already found something. I'll post an update for review this evening.
In D48330#1108326, @christos wrote:Pushed a fix for gcc builds: https://cgit.freebsd.org/src/commit/?id=f6631da0b581b28c2bfeea1199b52013bb46aa41
Jan 21 2025
Jan 21 2025
dev_submerge.ch added a comment to D48435: sound: Report actual vchanrate and vchanformat in sysctl.
Aren't vchanrate and vchanformat now completely disconnected from the actual parameters of the primary channel, until a vchan is opened? This would mean there's no useful feedback for the user until a channel is opened, at which point the parameters could suddenly change to something different?
I see now that there's a chn_reset() following this for primary channels, which means the defaults here may be overridden if not compatible. Also my concern was in conjunction with D48435, but I think we have to fix it there.
Jan 19 2025
Jan 19 2025
dev_submerge.ch added inline comments to D48435: sound: Report actual vchanrate and vchanformat in sysctl.
dev_submerge.ch added inline comments to D48434: sound: Initialize channels with sane default rate and format.
Jan 18 2025
Jan 18 2025
In D47917#1106149, @christos wrote:I'm still a bit conflicted as to what approach is the best for this patch specifically. It's probably better not to over-complicate this patch, and instead either leave the vchanrate and vchanformat sysctls uninitialized until the first vchan is created, or just hardcode some value.
@dev_submerge.ch What do you think?
Jan 17 2025
Jan 17 2025
Hopefully the last update, sorry for the breakage in the commits based on this. If there's no further issues, we should get this into CI for all supported architectures - then verify that this test passes everywhere before merging the followup commits with the refactorings.
Extend tests and restructure test data:
- Label each row of test data explicitly.
- Replace normalized test values with non-UB normalize function.
- Test read / write macros that use 24 bit samples for 32 bit calculation.
- Rename some helper functions for clarity.
Jan 13 2025
Jan 13 2025
Jan 12 2025
Jan 12 2025
There's actually three different sample value types involved here:
This currently shifts 32bit samples out of the 32bit range in case SND_PCM_64 is not set. sample << PCM_FXSHIFT happens twice. The root cause is in D47932 though.
Jan 11 2025
Jan 11 2025
Unfortunately the last two changes leave the vchanformat uninitialized until the channel's first use:
Jan 10 2025
Jan 10 2025
dev_submerge.ch added inline comments to D48330: sound: Unit test the pcm sample read and write macros.
Address some of the comments:
- Turn test data into a const array.
- Read samples from the local buffer, as intended.
- Test u-law and A-law sample formats.
- Extra test case to check the AFMT_BIT macro for correctness.
- Add a high level comment on the scope of the tests.
Jan 9 2025
Jan 9 2025
In D47917#1103675, @christos wrote:In D47917#1103672, @dev_submerge.ch wrote:I guess that's because of D47917, which assigns vchanrate to VCHAN_DEFAULT_RATE (48000), during attach in pcm_init(). Perhaps we should initialize these values once the primary channels have been created, and use their rates instead of defaulting to VCHAN_DEFAULT_RATE. I suppose the same should apply to the format.
Original discussion on D48336. Apart from that I think we're done, at least from my side.
Do you agree with this approach? The patch will need some refactoring but I think it should work.
I guess that's because of D47917, which assigns vchanrate to VCHAN_DEFAULT_RATE (48000), during attach in pcm_init(). Perhaps we should initialize these values once the primary channels have been created, and use their rates instead of defaulting to VCHAN_DEFAULT_RATE. I suppose the same should apply to the format.
Jan 8 2025
Jan 8 2025
dev_submerge.ch added a comment to D48336: sound: Handle multiple primary channel cases in vchan sysctls.
In D48336#1102813, @dev_submerge.ch wrote:Regarding the vchanrate setting, the main difference is probably that this USB interface supports only one sample rate (selected via hardware switch). If I set it to 44.1kHz, the behavior is somewhat strange:
root@current:~ # sysctl dev.pcm.0.rec.vchanrate dev.pcm.0.rec.vchanrate: 48000 root@current:~ # sysctl dev.pcm.0.play.vchanrate=96000 dev.pcm.0.play.vchanrate: 48000 -> 44100 root@current:~ # sysctl dev.pcm.0.rec.vchanrate=96000 dev.pcm.0.rec.vchanrate: 48000 -> 44100 root@current:~ # sysctl dev.pcm.0.rec.vchanrate=48000 dev.pcm.0.rec.vchanrate: 44100 -> 44100 root@current:~ # sysctl dev.pcm.0.rec.vchanrate=96000 dev.pcm.0.rec.vchanrate: 44100 -> 44100It seems to adopt the hardware sample rate, instead of accepting the user defined one. I'm not sure whether this is actually a bad thing, but it's neither consistent with the other settings nor with previous behavior.
Jan 7 2025
Jan 7 2025
dev_submerge.ch added a comment to D48336: sound: Handle multiple primary channel cases in vchan sysctls.
In D48336#1102814, @christos wrote:In D48336#1102813, @dev_submerge.ch wrote:It seems to adopt the hardware sample rate, instead of accepting the user defined one. I'm not sure whether this is actually a bad thing, but it's neither consistent with the other settings nor with previous behavior.
I am trying to understand how the patch would affect this behavior though. The previous implementation picks the first primary channel in a given direction, and this one loops through them, discarding the opposite direction's ones. With 1 primary channel per direction the behavior should be exactly the same. Are you sure this isn't the case without the patches, or at least not this one?
dev_submerge.ch added a comment to D48336: sound: Handle multiple primary channel cases in vchan sysctls.
No problem, I suppose you just wanted to test the attention of us reviewers ;-)
dev_submerge.ch added a comment to D48336: sound: Handle multiple primary channel cases in vchan sysctls.
With this stack of changes I'm not able to set a different vchanrate than the 48000 default value. Didn't investigate yet, Christos can you reproduce this?
Jan 6 2025
Jan 6 2025
Christos, I hope it's ok for me to "hijack" your refactoring efforts with this unit test, but I think it's the proper way forward with D47932. If this test succeeds now on all supported architectures, I'll be much more confident about the correctness of the test and test data. We can then adapt it to test your refactored pcm_sample_read() and pcm_sample_write() functions.
Jan 3 2025
Jan 3 2025
Please note that I'm working on a unit test which exercises the original sample read / write macros, to be committed before this refactoring. This way we can verify the test procedure and test data with the original code, then adapt it to the refactored code. It's still WIP, but I can already tell that we definitely have some regressions here.
Dec 31 2024
Dec 31 2024
Dec 30 2024
Dec 30 2024
In D48032#1100281, @markj wrote:I suspect that to make sure this works as expected, you would also want to introduce functions like
static void __noinline feed_eq_biquad_s16(...) { feed_eq_biquad(..., AFMT_S16_NE); }and call those from the switch statement instead. That would make the programmer's intent more obvious, and prevent the compiler from trying to deduplicate the inlined code.
Dec 29 2024
Dec 29 2024
In D48032#1100138, @christos wrote:Bump.
dev_submerge.ch added inline comments to D48185: sound: Do not fail from vchan_destroy() if children list is empty.
In D47918#1100131, @christos wrote:In D47918#1099644, @dev_submerge.ch wrote:Not a consequence of your changes here, but it seems we only set the vchan settings on the first channel per direction. There could be multiple, right?
IIRC, there's only one or two sound drivers that support multiple channels per direction. Maybe we should evaluate whether that's actually required and worth the complication it causes throughout the sound module.
There are more places in pcm/ where we always pick the first primary channel. I guess we could implement some heuristics, like choosing the first non-busy channel, or else fall back to the first channel, or the channel with the least vchans, in order to balance things out, but that would require multiple changes throughout sound(4), so we could discuss this further in an email.
Dec 28 2024
Dec 28 2024
dev_submerge.ch added inline comments to D48185: sound: Do not fail from vchan_destroy() if children list is empty.
Not a consequence of your changes here, but it seems we only set the vchan settings on the first channel per direction. There could be multiple, right?
In D47932#1099442, @netchild wrote:In D47932#1099399, @dev_submerge.ch wrote:Thanks for your input. I agree that we should keep an eye on performance, but I'd like to clarify: In our current refactoring of the format conversion we're not touching anything that changes the buffer sizes. And that's the only thing that could possibly affect audio latency. If latency really is of concern, then we'd have to look at smaller buffer sizes and how to make timers and scheduling more reliable. Also I doubt that we ever had the lowest overall latency, if you count in ASIO on Windows. I suspect that was about the latency introduced by the resampler.
We have the possibility to modify the latency / buffer size already. See https://meka.rs/blog/2017/01/25/sing-beastie-sing/
Dec 27 2024
Dec 27 2024
In D47932#1099384, @netchild wrote:FYI: at some point we had the sound system with the lowest latency. Ariff was comparing MS, OS X and Linux. I do not know if they have catched-up since then, but it may be worth the effort to check the performance / latency for such changes. Unfortunately I haven't found the info about the latency stuff he did, only his resampling quality comparison with other resampler implementations (https://people.freebsd.org/~ariff/z_comparison/). In https://people.freebsd.org/~ariff/old/ he has some old low latency diffs, so some interested soul could check which parts he modified to get lower latency.
Dec 26 2024
Dec 26 2024
I stumbled upon that repeated list traversal when reviewing D48185. The implementation is roughly based on SLIST_REMOVE(). Compared to CHN_REMOVE(), the difference in performance should be only minuscule, doing one additional NULL pointer check per iteration. Therefore we may want to consider using the safe variant everywhere.
dev_submerge.ch added inline comments to D48185: sound: Do not fail from vchan_destroy() if children list is empty.
Dec 24 2024
Dec 24 2024
dev_submerge.ch accepted D48156: sound: Do not return an error from chn_notify() if the children list is empty.
I can confirm that this fixes the panic experienced with D47917, and I don't see anything else that could be affected by the change in return value. Thank you!
Dec 19 2024
Dec 19 2024
In D47917#1097943, @christos wrote:Interesting. Does calling chn_abort() on the vchan in dsp_close() before the call to vchan_destroy() fix this?
First of all, could you please update these reviews when you rebase? The diff here still has D47868 included, and thus fails to apply cleanly.
Dec 17 2024
Dec 17 2024
In D47917#1097206, @dev_submerge.ch wrote:Ok, I did some more debugging, my current theory is this:
- The first (and only) playback vchan is closed while running, we call vchan_destroy().
- vchan_destroy() removes the vchan from its parent's children list.
- vchan_destroy() calls chn_kill(), which in turn calls chn_trigger(ABORT).
- chn_trigger(ABORT) calls vchan_trigger() through the object method.
- vchan_trigger() calls chn_notify() on the parent.
- chn_notify() fails with ENODEV because the parent's children list is empty now.
- Thus vchan_trigger() also fails, ENODEV.
- chn_trigger(ABORT) fails early and doesn't remove the vchan from the channels.pcm.busy list.
- chn_kill() frees the vchan data, leaving a stale entry in channels.pcm.busy.
- Next occasion to traverse channels.pcm.busy list -> panic!
So a precondition of this panic would be that there's one vchan open which gets closed abruptly, instead of being stopped. This seems to hold in my experiments, as I cannot trigger the panic while keeping a vchan open.
Ok, I did some more debugging, my current theory is this:
In D47917#1096878, @christos wrote:In D47917#1096435, @dev_submerge.ch wrote:In D47917#1096289, @christos wrote:In D47917#1095391, @dev_submerge.ch wrote:Interesting, I am not able to reproduce this. Does this happen with a different player than sox as well? Not sure how this patch could be responsible for this, though. All it does is essentially allocate vchans on open() and delete them on close(), instead of keeping them around after close().
I now isolated the panic to this patch (on top of D47868 which is required to build). It also happens with cat /dev/zero > /dev/dsp instead of sox. The cat /dev/sndstat is not needed to reproduce it. I did a full system build / install with and without this patch, consistent results.
I applied just D47868 and this one and still cannot reproduce the panic... Tried all the tests I have in the test section here, as well as what you mentioned, with both vchans enabled or disabled, including bitperfect. Judging from your backtraces, it seems that the panics most likely occur at the CHN_INSERT_HEAD_SAFE()/CHN_REMOVE_SAFE() calls. Is there something worth noting in your setup/test environment?
I will also work on addressing the issues in the inline comments.
Dec 16 2024
Dec 16 2024
In D48036#1096288, @christos wrote:Yeap... I shuffled some patches around to re-organize them in a more intuitive way, so it's quite a mess right now to apply the patches cleanly. The current sequence of patches in my local tree is (from oldest to newest):
sound: Clean up pcm/ includes sound: Bail out early if a format is not supported sound: Refactor the format conversion framework sound: Remove macro magic from pcm/feeder_eq.c sound: Remove FEEDEQ_CLAMP() sound: Cache bps in pcm/feeder_eq.c sound: Remove macro magic from pcm/feeder_matrix.c sound: Remove feed_matrix_apply_generic() sound: Implement AFMT_FLOAT support beep(1): Use AFMT_FLOAT sound: Allocate vchans on-demand sound: Simplify vchan_getparentchannel() sound: Remove SNDBUF_LOCKASSERT() sound: Improve afmt_tab sound: Get rid of redundant variables in chn_setspeed() and chn_setformat() sound: Return if the new speed/format is the same as the current one
FYI, the panic also happens on close:
In D47917#1096289, @christos wrote:In D47917#1095391, @dev_submerge.ch wrote:Interesting, I am not able to reproduce this. Does this happen with a different player than sox as well? Not sure how this patch could be responsible for this, though. All it does is essentially allocate vchans on open() and delete them on close(), instead of keeping them around after close().
In D48032#1096268, @christos wrote:In D48032#1095744, @dev_submerge.ch wrote:If you want to make your function equal to the macro in terms of performance, you have to call it with literal format parameters somehow. E.g. through a switch on the format parameters.
I do not have a benchmark right now to prove the opposite, but do you think such a performance hit is noticeable, if at all existent? Currently we use a function pointer to a specialized function (i.e one for each format), and the patch uses a generic function which fetches the format directly from the struct. I am not really well-versed with compiler optimizations, but I would suppose that the generic one is more likely to be inlined, and thus give us a performance boost (I did see the comment about CPU-branch prediction in D47932).
In D48033#1096266, @christos wrote:In D48033#1095717, @dev_submerge.ch wrote:Hm, PCM_CLAMP_S32 does something different when the SND_PCM_64 option is not set?
It does, but I am wondering whether the non-SND_PCM_64 is useful. I am not exactly sure why it does what it does.
Dec 15 2024
Dec 15 2024
In D48036#1096250, @christos wrote:In D48036#1095737, @dev_submerge.ch wrote:There's more #ifdef FEEDMATRIX_GENERIC code which references this, no?
No. D48035 removes the other code which assigns feed_matrix_apply_generic() as the callback.
Dec 13 2024
Dec 13 2024
Same as D48032, you may want to call your function with literal format parameters, for performance reasons.
If you want to make your function equal to the macro in terms of performance, you have to call it with literal format parameters somehow. E.g. through a switch on the format parameters.
There's more #ifdef FEEDMATRIX_GENERIC code which references this, no?
Why not just cache it in a local variable? That's probably cheaper, even though the "computation" here is trivial anyway.
Hm, PCM_CLAMP_S32 does something different when the SND_PCM_64 option is not set?
dev_submerge.ch added inline comments to D48031: sound: Bail out early if a format is not supported.
Dec 12 2024
Dec 12 2024
I have a hard time to apply these interdependent patches cleanly to my tree. @christos, do you update all affected patches in the series when doing a rebase?
In D47932#1094268, @christos wrote:In D47932#1093065, @dev_submerge.ch wrote:
- I strongly suggest a unit test for the format conversions.
What exactly do we want to test? If converting a sample X from format1 to format2 will give us the intended Y result?
Dec 6 2024
Dec 6 2024
Overall I like the direction of this change, but I still see some major issues:
Dec 5 2024
Dec 5 2024
In D47917#1092787, @christos wrote:In D47917#1092710, @dev_submerge.ch wrote:In D47917#1092486, @christos wrote:Some notes:
- I would like a different name than hw.snd.maxautovchans since the functionality is different now. Maybe hw.snd.vchans? That would break compatibility though. In any case, I will add a RELNOTES entry when it's time to commit.
This implementation is more like a default value for the dev.pcm.X.vchans, maybe default_vchans or autovchans?
The patch makes it so that maxautovchans behaves like a global switch for vchans, which can be overriden by the individual dev.pcm.X.[play|rec].vchans controls. So IMHO default_vchans doesn't really apply here. autovchans could work, but I think simply vchans is more intuitive. What do you think?