It is plausible that hardware interrupts a host only when GIS goes from zero
to one. GIS is formed by OR-ing multiple hardware statuses, so it's
possible that a previously cleared status gets set again while another
status has not been cleared yet. Thus, there will be no new interrupt as
GIS always stayed set. If we don't re-examine GIS then we can leave it set
and never get an interrupt again.
Without this change I frequently saw a problem where snd_hda would stop
working. Setting dev.hdac.1.polling=1 would bring it back to life and
afterwards I could set polling back to zero. Sometimes the problem started
right after a boot, sometimes it happened after resuming from S3, frequently
it would occur when sound output and input are active concurrently (such as
during conferencing).
I looked at HDAC_INTSTS while the sound was not working and I saw that both
HDAC_INTSTS_GIS and HDAC_INTSTS_CIS were set, but there were no interrupts.
I have collected some statistics over a period of several days about how
many loops (calls to hdac_one_intr) the new code did for a single interrupt:
Loops | Times Happened |
---|---|
0 | 301 |
1 | 12857746 |
2 | 280 |
3 | 2 |
4+ | 0 |
I believe that previously the sound would get stuck each time we had to loop
more than once.
The hardware in question:
hdac1: <AMD (0x15e3) HDA Controller> mem 0xfe680000-0xfe687fff at device 0.6 on pci4 hdacc1: <Realtek ALC269 HDA CODEC> at cad 0 on hdac1