summary refs log tree commit diff
diff options
context:
space:
mode:
authorpaulhsia <paulhsia@chromium.org>2019-10-04 20:02:49 +0800
committerCommit Bot <commit-bot@chromium.org>2019-10-08 11:53:24 +0000
commit0b6f02fea7716ec5752555ea44aafed214b58faa (patch)
tree4814c5eed59918dc84eaa7e883c0fdb9882ffdc3
parent7595d80248541434a8f4d93b5032b701cfdf4c7f (diff)
downloadcrosvm-0b6f02fea7716ec5752555ea44aafed214b58faa.tar
crosvm-0b6f02fea7716ec5752555ea44aafed214b58faa.tar.gz
crosvm-0b6f02fea7716ec5752555ea44aafed214b58faa.tar.bz2
crosvm-0b6f02fea7716ec5752555ea44aafed214b58faa.tar.lz
crosvm-0b6f02fea7716ec5752555ea44aafed214b58faa.tar.xz
crosvm-0b6f02fea7716ec5752555ea44aafed214b58faa.tar.zst
crosvm-0b6f02fea7716ec5752555ea44aafed214b58faa.zip
device: ac97: Cleanup interrupt logic
- Send only one event while re-sampling.
- Don't sent event if the new sr is identical to the old one

This can reduce the rate to trigger the issue.

BUG=chromium:937977
TEST=Build and run lots of aplay and arecord in guest vm

Change-Id: Ibd21f363076c977ae256079e2615094b7ed2408b
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/1840752
Tested-by: Chih-Yang Hsia <paulhsia@chromium.org>
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Daniel Verkamp <dverkamp@chromium.org>
Reviewed-by: Dylan Reid <dgreid@chromium.org>
Commit-Queue: Chih-Yang Hsia <paulhsia@chromium.org>
-rw-r--r--devices/src/pci/ac97_bus_master.rs20
1 files changed, 8 insertions, 12 deletions
diff --git a/devices/src/pci/ac97_bus_master.rs b/devices/src/pci/ac97_bus_master.rs
index 12a4f74..83c0021 100644
--- a/devices/src/pci/ac97_bus_master.rs
+++ b/devices/src/pci/ac97_bus_master.rs
@@ -235,19 +235,12 @@ impl Ac97BusMaster {
                 {
                     // Scope for the lock on thread_regs.
                     let regs = thread_regs.lock();
-                    // Check output irq
+                    // Check output and input irq
                     let po_int_mask = regs.func_regs(Ac97Function::Output).int_mask();
-                    if regs.func_regs(Ac97Function::Output).sr & po_int_mask != 0 {
-                        if let Some(irq_evt) = regs.irq_evt.as_ref() {
-                            if let Err(e) = irq_evt.write(1) {
-                                error!("Failed to set the irq from the resample thread: {}.", e);
-                                break;
-                            }
-                        }
-                    }
-                    // Check input irq
                     let pi_int_mask = regs.func_regs(Ac97Function::Input).int_mask();
-                    if regs.func_regs(Ac97Function::Input).sr & pi_int_mask != 0 {
+                    if regs.func_regs(Ac97Function::Output).sr & po_int_mask != 0
+                        || regs.func_regs(Ac97Function::Input).sr & pi_int_mask != 0
+                    {
                         if let Some(irq_evt) = regs.irq_evt.as_ref() {
                             if let Err(e) = irq_evt.write(1) {
                                 error!("Failed to set the irq from the resample thread: {}.", e);
@@ -753,14 +746,17 @@ fn update_sr(regs: &mut Ac97BusMasterRegs, func: Ac97Function, val: u16) {
 
     {
         let func_regs = regs.func_regs_mut(func);
+        let old_sr = func_regs.sr;
         func_regs.sr = val;
-        if val & SR_INT_MASK != 0 {
+        if (old_sr ^ val) & SR_INT_MASK != 0 {
             if (val & SR_LVBCI) != 0 && (func_regs.cr & CR_LVBIE) != 0 {
                 interrupt_high = true;
             }
             if (val & SR_BCIS) != 0 && (func_regs.cr & CR_IOCE) != 0 {
                 interrupt_high = true;
             }
+        } else {
+            return;
         }
     }