diff options
author | Suresh Siddha <suresh.b.siddha@intel.com> | 2008-10-16 19:31:54 -0400 |
---|---|---|
committer | David Woodhouse <David.Woodhouse@intel.com> | 2008-10-17 03:03:05 -0400 |
commit | f05810c9962bba3e809f07619bda1bfdebbfbfb9 (patch) | |
tree | d226f13a0d93cda208f9aea85d2a9ac29086f3e1 | |
parent | 2e532d68a2b3e2aa6b19731501222069735c741c (diff) |
dmar: use spin_lock_irqsave() in qi_submit_sync()
Next patch in the series will use queued invalidation interface
qi_submit_sync() for DMA-remapping aswell, which can be called from interrupt
context.
So use spin_lock_irqsave() instead of spin_lock() in qi_submit_sync().
Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com>
Signed-off-by: Youquan Song <youquan.song@intel.com>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
-rw-r--r-- | drivers/pci/dmar.c | 19 |
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 | /* |