aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/dmar.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci/dmar.c')
-rw-r--r--drivers/pci/dmar.c19
1 files changed, 13 insertions, 6 deletions
diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c
index e842e756308a..b64cec190542 100644
--- a/drivers/pci/dmar.c
+++ b/drivers/pci/dmar.c
@@ -580,11 +580,11 @@ void qi_submit_sync(struct qi_desc *desc, struct intel_iommu *iommu)
580 580
581 hw = qi->desc; 581 hw = qi->desc;
582 582
583 spin_lock(&qi->q_lock); 583 spin_lock_irqsave(&qi->q_lock, flags);
584 while (qi->free_cnt < 3) { 584 while (qi->free_cnt < 3) {
585 spin_unlock(&qi->q_lock); 585 spin_unlock_irqrestore(&qi->q_lock, flags);
586 cpu_relax(); 586 cpu_relax();
587 spin_lock(&qi->q_lock); 587 spin_lock_irqsave(&qi->q_lock, flags);
588 } 588 }
589 589
590 index = qi->free_head; 590 index = qi->free_head;
@@ -605,15 +605,22 @@ void qi_submit_sync(struct qi_desc *desc, struct intel_iommu *iommu)
605 qi->free_head = (qi->free_head + 2) % QI_LENGTH; 605 qi->free_head = (qi->free_head + 2) % QI_LENGTH;
606 qi->free_cnt -= 2; 606 qi->free_cnt -= 2;
607 607
608 spin_lock_irqsave(&iommu->register_lock, flags); 608 spin_lock(&iommu->register_lock);
609 /* 609 /*
610 * update the HW tail register indicating the presence of 610 * update the HW tail register indicating the presence of
611 * new descriptors. 611 * new descriptors.
612 */ 612 */
613 writel(qi->free_head << 4, iommu->reg + DMAR_IQT_REG); 613 writel(qi->free_head << 4, iommu->reg + DMAR_IQT_REG);
614 spin_unlock_irqrestore(&iommu->register_lock, flags); 614 spin_unlock(&iommu->register_lock);
615 615
616 while (qi->desc_status[wait_index] != QI_DONE) { 616 while (qi->desc_status[wait_index] != QI_DONE) {
617 /*
618 * We will leave the interrupts disabled, to prevent interrupt
619 * context to queue another cmd while a cmd is already submitted
620 * and waiting for completion on this cpu. This is to avoid
621 * a deadlock where the interrupt context can wait indefinitely
622 * for free slots in the queue.
623 */
617 spin_unlock(&qi->q_lock); 624 spin_unlock(&qi->q_lock);
618 cpu_relax(); 625 cpu_relax();
619 spin_lock(&qi->q_lock); 626 spin_lock(&qi->q_lock);
@@ -622,7 +629,7 @@ void qi_submit_sync(struct qi_desc *desc, struct intel_iommu *iommu)
622 qi->desc_status[index] = QI_DONE; 629 qi->desc_status[index] = QI_DONE;
623 630
624 reclaim_free_desc(qi); 631 reclaim_free_desc(qi);
625 spin_unlock(&qi->q_lock); 632 spin_unlock_irqrestore(&qi->q_lock, flags);
626} 633}
627 634
628/* 635/*