4c7d1ab06d
It is plausible that the 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 another 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 tested hardware is: hdac1: <AMD (0x15e3) HDA Controller> mem 0xfe680000-0xfe687fff at device 0.6 on pci4 hdacc1: <Realtek ALC269 HDA CODEC> at cad 0 on hdac1 No objections: mav MFC after: 5 weeks Differential Revision: https://reviews.freebsd.org/D25128