[patch 1/4] dmar: use spin_lock_irqsave() in qi_submit_sync()

From: Suresh Siddha
Date: Thu Oct 16 2008 - 19:46:28 EST


From: Suresh Siddha <suresh.b.siddha@xxxxxxxxx>
Subject: 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@xxxxxxxxx>
Signed-off-by: Youquan Song <youquan.song@xxxxxxxxx>
---

Index: tip/drivers/pci/dmar.c
===================================================================
--- tip.orig/drivers/pci/dmar.c 2008-10-07 15:42:47.000000000 -0700
+++ tip/drivers/pci/dmar.c 2008-10-07 16:27:47.000000000 -0700
@@ -592,11 +592,11 @@

hw = qi->desc;

- spin_lock(&qi->q_lock);
+ spin_lock_irqsave(&qi->q_lock, flags);
while (qi->free_cnt < 3) {
- spin_unlock(&qi->q_lock);
+ spin_unlock_irqrestore(&qi->q_lock, flags);
cpu_relax();
- spin_lock(&qi->q_lock);
+ spin_lock_irqsave(&qi->q_lock, flags);
}

index = qi->free_head;
@@ -617,15 +617,22 @@
qi->free_head = (qi->free_head + 2) % QI_LENGTH;
qi->free_cnt -= 2;

- spin_lock_irqsave(&iommu->register_lock, flags);
+ spin_lock(&iommu->register_lock);
/*
* update the HW tail register indicating the presence of
* new descriptors.
*/
writel(qi->free_head << 4, iommu->reg + DMAR_IQT_REG);
- spin_unlock_irqrestore(&iommu->register_lock, flags);
+ spin_unlock(&iommu->register_lock);

while (qi->desc_status[wait_index] != QI_DONE) {
+ /*
+ * We will leave the interrupts disabled, to prevent interrupt
+ * context to queue another cmd while a cmd is already submitted
+ * and waiting for completion on this cpu. This is to avoid
+ * a deadlock where the interrupt context can wait indefinitely
+ * for free slots in the queue.
+ */
spin_unlock(&qi->q_lock);
cpu_relax();
spin_lock(&qi->q_lock);
@@ -634,7 +641,7 @@
qi->desc_status[index] = QI_DONE;

reclaim_free_desc(qi);
- spin_unlock(&qi->q_lock);
+ spin_unlock_irqrestore(&qi->q_lock, flags);
}

/*

--

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/