* timer/sequencer driver issues: pulling my grey hair out
@ 2005-10-18 21:00 Andreas Mohr
2005-10-19 3:33 ` Lee Revell
2005-10-19 7:56 ` Clemens Ladisch
0 siblings, 2 replies; 4+ messages in thread
From: Andreas Mohr @ 2005-10-18 21:00 UTC (permalink / raw)
To: alsa-devel
Hi all,
ok, it's not THAT bad yet, but I've certainly spent some consecutive 3
evenings or so trying to get the azt3328 DirectX timer accepted as
a *well-working* ALSA sequencer timer.
This timer has:
- a maximum tick value of 1048575 in its value register
- a frequency of 1024000/s, it seems (a 1000 value got me exactly 1024 IRQs
per second in syslog)
Thus its main characteristics are:
static int snd_azf3328_timer_precise_resolution(snd_timer_t *timer,
unsigned long *num, unsigned long *den)
{
snd_azf3328_dbgcallenter();
*num = 1;
*den = 1024000;
snd_azf3328_dbgcallleave();
return 0;
}
static struct _snd_timer_hardware snd_azf3328_timer_hw = {
.flags = SNDRV_TIMER_HW_AUTO,
.resolution = 977, /* 1000000/1024000 = 0.9765625us */
.ticks = 1048576, /* max tick count, defined by the value register */
.start = snd_azf3328_timer_start,
.stop = snd_azf3328_timer_stop,
.precise_resolution = snd_azf3328_timer_precise_resolution,
};
Now if I'm optimistic and let these values harrass a
schedtool -I -p 0 -e timidity -iAv -B2,8 -Os -EFreverb=0
pmidi -p 128:0 /home/andi/jazz.mid
, then all I get is a completely locked-up PC.
Why?
Simple! It's because the program sets an sticks value of 1, since my
timer announces a very high-speed resolution.
This of course results in an IRQ DoS which completely locks up my PC,
due to triggering a timer IRQ every 0.976us.
Now I've seen that snd_emu10k1_timer_start() has the following very nice code:
static int snd_emu10k1_timer_start(snd_timer_t *timer)
{
emu10k1_t *emu;
unsigned long flags;
unsigned int delay;
emu = snd_timer_chip(timer);
delay = timer->sticks - 1;
if (delay < 5 ) /* minimum time is 5 ticks */
delay = 5;
spin_lock_irqsave(&emu->reg_lock, flags);
snd_emu10k1_intr_enable(emu, INTE_INTERVALTIMERENB);
outw(delay & TIMER_RATE_MASK, emu->port + TIMER);
spin_unlock_irqrestore(&emu->reg_lock, flags);
return 0;
}
IOW, if the sticks value is too low, it will *bend* it to a minimum value
of 5, i.e. 100us in this card timer's case.
Since this 5 value translates to about a 110 value in my case to reach about
100us, too, I did that modification, which resulted in a working MIDI output
which *finally* didn't stop after the first note (I had timer value issues
before due to completely wrong _snd_timer_hardware configuration, so
the music execution was *very* slow).
Again, with the new 110 limit value the music now started playing several
notes, however *very* slow (one note every 10 seconds or so),
most likely **since the program didn't know at all about my evil
backyard tweak** and instead did its timing calculations with the assumption
of my timer using the sticks value of 1 it asked me to set.
IOW, the 5 value limitation in snd_emu10k1_timer_start will *break*
correct timing execution - its only purpose seems to be to protect the
PC from timer IRQ overload conditions.
In my case, the situation is *terribly* aggravated, since I'm not simply
using a 48kHz timer, but a >1MHz timer even which can much more easily
cause timer IRQ overload!
Questions:
- why is the program configuring a dangerously low sticks value of 1?
Is it due to a remaining misdeclaration of my timer attributes somewhere,
or is it because of this program being stupid in its timer parameter choice?
- it's a very good idea to get rid of the "stupid" *hidden* sticks bending
in snd_emu10k1_timer_start(), right? Preferrably use an intelligent
communication instead that makes sure that the program uses an sticks value
that won't cause IRQ overload?
One currently doable way of handling this overload problem would be to
*algorithmically* down-scale the resolution of my timer and then announce
a lower-res timer in _snd_timer_hardware, thus making sure that only
timer countdown values of say > 256 will be configured by my driver
and the program is *properly* informed about what *exactly* my (now virtual)
timer resolution is.
But this seems to be somewhat stupid IMHO.
For now I'll go with this software down-scaling approach, but if you have
any better idea or can tell me where I'm terribly wrong, then just go ahead
and tell me!
Thanks!
Andreas Mohr
-------------------------------------------------------
This SF.Net email is sponsored by:
Power Architecture Resource Center: Free content, downloads, discussions,
and more. http://solutions.newsforge.com/ibmarch.tmpl
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: timer/sequencer driver issues: pulling my grey hair out
2005-10-18 21:00 timer/sequencer driver issues: pulling my grey hair out Andreas Mohr
@ 2005-10-19 3:33 ` Lee Revell
2005-10-19 6:52 ` Andreas Mohr
2005-10-19 7:56 ` Clemens Ladisch
1 sibling, 1 reply; 4+ messages in thread
From: Lee Revell @ 2005-10-19 3:33 UTC (permalink / raw)
To: andi; +Cc: alsa-devel
On Tue, 2005-10-18 at 23:00 +0200, Andreas Mohr wrote:
> - why is the program configuring a dangerously low sticks value of 1?
> Is it due to a remaining misdeclaration of my timer attributes
> somewhere, or is it because of this program being stupid in its timer
> parameter choice?
Sorry, no idea. The timer API is the one part of ALSA that is still
quite poorly documented. Does the timer test utility that comes with
alsa-lib work?
> - it's a very good idea to get rid of the "stupid" *hidden* sticks
> bending in snd_emu10k1_timer_start(), right? Preferrably use an
> intelligent communication instead that makes sure that the program
> uses an sticks value that won't cause IRQ overload?
>
I just copied this code over from the OSS driver. I have no reason to
think it's correct. All the information we have on the emu10k1's
interval timer comes from these comment by some anonymous Creative
engineer in emu10k1.h:
263 #define TIMER 0x1a /* Timer terminal count register */
264 /* NOTE: After the rate is changed, a maximum */
265 /* of 1024 sample periods should be allowed */
266 /* before the new rate is guaranteed accurate. */
267 #define TIMER_RATE_MASK 0x000003ff /* Timer interrupt rate in sample periods */
268 /* 0 == 1024 periods, [1..4] are not useful */
Lee
-------------------------------------------------------
This SF.Net email is sponsored by:
Power Architecture Resource Center: Free content, downloads, discussions,
and more. http://solutions.newsforge.com/ibmarch.tmpl
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: timer/sequencer driver issues: pulling my grey hair out
2005-10-19 3:33 ` Lee Revell
@ 2005-10-19 6:52 ` Andreas Mohr
0 siblings, 0 replies; 4+ messages in thread
From: Andreas Mohr @ 2005-10-19 6:52 UTC (permalink / raw)
To: Lee Revell; +Cc: andi, alsa-devel
Hi,
ah, you again, and fast response, too :)
On Tue, Oct 18, 2005 at 11:33:52PM -0400, Lee Revell wrote:
> On Tue, 2005-10-18 at 23:00 +0200, Andreas Mohr wrote:
> > - why is the program configuring a dangerously low sticks value of 1?
> > Is it due to a remaining misdeclaration of my timer attributes
> > somewhere, or is it because of this program being stupid in its timer
> > parameter choice?
>
> Sorry, no idea. The timer API is the one part of ALSA that is still
> quite poorly documented. Does the timer test utility that comes with
> alsa-lib work?
I cannot confirm that currently. It was no help whatsoever in implementing
this timer, instead I used timidity/pmidi (with a reconfigured snd-seq module,
of course), since that provided some actual acustical feedback.
But I guess it should work now, given that I actually managed to achieve useful
operation yesterday, by adding a down-scale define of 100 which thus downscaled
my 10240000Hz timer to 10240Hz, enough to not cause an IRQ storm anymore and
allow the CPU (1.8GHz Athlon) to keep up with the extreme CPU requirements of
timidity (a scale factor of 50 already caused rather weird sound playback
effects due to CPU overload).
So it's finally working relatively fine, whew.
(BTW, I'm getting 10% hardirq and 5% softirq CPU load when playing that MIDI
song when downscaling by 100)
And that with an INSANELY optimized IRQ handler in my driver, mind you.
I'm planning to add an azt3328 module parameter to adjust this downscale value
manually.
> > - it's a very good idea to get rid of the "stupid" *hidden* sticks
> > bending in snd_emu10k1_timer_start(), right? Preferrably use an
> > intelligent communication instead that makes sure that the program
> > uses an sticks value that won't cause IRQ overload?
> >
>
> I just copied this code over from the OSS driver. I have no reason to
> think it's correct. All the information we have on the emu10k1's
> interval timer comes from these comment by some anonymous Creative
> engineer in emu10k1.h:
>
> 263 #define TIMER 0x1a /* Timer terminal count register */
> 264 /* NOTE: After the rate is changed, a maximum */
> 265 /* of 1024 sample periods should be allowed */
> 266 /* before the new rate is guaranteed accurate. */
> 267 #define TIMER_RATE_MASK 0x000003ff /* Timer interrupt rate in sample periods */
> 268 /* 0 == 1024 periods, [1..4] are not useful */
I'm just about 100% certain that this comment is due to the IRQ overload
issues. Or OTOH maybe even the emu10k1 itself doesn't manage to trigger an
IRQ properly with such a fast setting (but I highly doubt that one, it must
simply be a CPU speed issue).
I'm going to polish my driver today and then submit it ASAP.
Andreas Mohr
-------------------------------------------------------
This SF.Net email is sponsored by:
Power Architecture Resource Center: Free content, downloads, discussions,
and more. http://solutions.newsforge.com/ibmarch.tmpl
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: timer/sequencer driver issues: pulling my grey hair out
2005-10-18 21:00 timer/sequencer driver issues: pulling my grey hair out Andreas Mohr
2005-10-19 3:33 ` Lee Revell
@ 2005-10-19 7:56 ` Clemens Ladisch
1 sibling, 0 replies; 4+ messages in thread
From: Clemens Ladisch @ 2005-10-19 7:56 UTC (permalink / raw)
To: Andreas Mohr; +Cc: Lee Revell, alsa-devel
Andreas Mohr wrote:
> This timer has:
> - a frequency of 1024000/s
> [...]
> pmidi -p 128:0 /home/andi/jazz.mid
> , then all I get is a completely locked-up PC.
>
> Why?
> Simple! It's because the program sets an sticks value of 1, since my
> timer announces a very high-speed resolution.
> This of course results in an IRQ DoS which completely locks up my PC,
> due to triggering a timer IRQ every 0.976us.
This is a bug in the sequencer timer code -- it uses the maximum
available frequency when no default has been set (that would be done
with the seq_default_timer_resolution parameter of the snd-seq
module).
> Now I've seen that snd_emu10k1_timer_start() has the following very nice code:
>
> delay = timer->sticks - 1;
> if (delay < 5 ) /* minimum time is 5 ticks */
> delay = 5;
>
> IOW, if the sticks value is too low, it will *bend* it to a minimum value
> of 5, i.e. 100us in this card timer's case.
> Since this 5 value translates to about a 110 value in my case to reach about
> 100us, too, I did that modification, which resulted in a working MIDI output
> which *finally* didn't stop after the first note (I had timer value issues
> before due to completely wrong _snd_timer_hardware configuration, so
> the music execution was *very* slow).
>
> Again, with the new 110 limit value the music now started playing several
> notes, however *very* slow (one note every 10 seconds or so),
> most likely **since the program didn't know at all about my evil
> backyard tweak** and instead did its timing calculations with the assumption
> of my timer using the sticks value of 1 it asked me to set.
>
> IOW, the 5 value limitation in snd_emu10k1_timer_start will *break*
> correct timing execution - its only purpose seems to be to protect the
> PC from timer IRQ overload conditions.
That code is based on my code for the ymfpci timer which has a similar
lower limit which is due to a hardware limitation (the ymfpci timer
has 96 kHz resolution, but the maximum frequency is 48 kHz).
I guess I should just declare the timer to have 48 kHz resolution as
long as the timer core doesn't know about minimum tick lengths that
are greater that the resolution.
> In my case, the situation is *terribly* aggravated, since I'm not simply
> using a 48kHz timer, but a >1MHz timer even which can much more easily
> cause timer IRQ overload!
>
> Questions:
> - why is the program configuring a dangerously low sticks value of 1?
Because I haven't yet applied the patch I'm writing just now that
limits the sequencer timer frequency to some sane value.
> - it's a very good idea to get rid of the "stupid" *hidden* sticks bending
> in snd_emu10k1_timer_start(), right?
Yes. I'll do this for the ymfpci driver.
Lee, I don't know if the 5 ticks limit is a hardware limitation of the
Emu10k1. The comment you quoted seems to indicate it's not. I guess
we should just allow a frequency of 48 kHz; the sequencer won't
actually use it.
Regards,
Clemens
-------------------------------------------------------
This SF.Net email is sponsored by:
Power Architecture Resource Center: Free content, downloads, discussions,
and more. http://solutions.newsforge.com/ibmarch.tmpl
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2005-10-19 7:56 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-10-18 21:00 timer/sequencer driver issues: pulling my grey hair out Andreas Mohr
2005-10-19 3:33 ` Lee Revell
2005-10-19 6:52 ` Andreas Mohr
2005-10-19 7:56 ` Clemens Ladisch
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.