aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2009-11-19 19:10:37 -0500
committerDan Williams <dan.j.williams@intel.com>2009-11-20 01:21:03 -0500
commit7b3cc2b1fc2066391e498f3387204908c4eced21 (patch)
tree8a2bc28955710c580201046d04843773cb7d87a1
parent4499a24dec00e037da7d09caccad45e7594a9c19 (diff)
async_tx: build-time toggling of async_{syndrome,xor}_val dma support
ioat3.2 does not support asynchronous error notifications which makes the driver experience latencies when non-zero pq validate results are expected. Provide a mechanism for turning off async_xor_val and async_syndrome_val via Kconfig. This approach is generally useful for any driver that specifies ASYNC_TX_DISABLE_CHANNEL_SWITCH and would like to force the async_tx api to fall back to the synchronous path for certain operations. Signed-off-by: Dan Williams <dan.j.williams@intel.com>
-rw-r--r--crypto/async_tx/Kconfig5
-rw-r--r--crypto/async_tx/async_pq.c14
-rw-r--r--crypto/async_tx/async_xor.c15
-rw-r--r--drivers/dma/Kconfig2
-rw-r--r--drivers/dma/dmaengine.c6
-rw-r--r--drivers/dma/ioat/dma_v3.c10
6 files changed, 46 insertions, 6 deletions
diff --git a/crypto/async_tx/Kconfig b/crypto/async_tx/Kconfig
index e5aeb2b79e6f..e28e276ac611 100644
--- a/crypto/async_tx/Kconfig
+++ b/crypto/async_tx/Kconfig
@@ -23,3 +23,8 @@ config ASYNC_RAID6_RECOV
23 select ASYNC_CORE 23 select ASYNC_CORE
24 select ASYNC_PQ 24 select ASYNC_PQ
25 25
26config ASYNC_TX_DISABLE_PQ_VAL_DMA
27 bool
28
29config ASYNC_TX_DISABLE_XOR_VAL_DMA
30 bool
diff --git a/crypto/async_tx/async_pq.c b/crypto/async_tx/async_pq.c
index 6b5cc4fba59f..ec87f53d5059 100644
--- a/crypto/async_tx/async_pq.c
+++ b/crypto/async_tx/async_pq.c
@@ -240,6 +240,16 @@ async_gen_syndrome(struct page **blocks, unsigned int offset, int disks,
240} 240}
241EXPORT_SYMBOL_GPL(async_gen_syndrome); 241EXPORT_SYMBOL_GPL(async_gen_syndrome);
242 242
243static inline struct dma_chan *
244pq_val_chan(struct async_submit_ctl *submit, struct page **blocks, int disks, size_t len)
245{
246 #ifdef CONFIG_ASYNC_TX_DISABLE_PQ_VAL_DMA
247 return NULL;
248 #endif
249 return async_tx_find_channel(submit, DMA_PQ_VAL, NULL, 0, blocks,
250 disks, len);
251}
252
243/** 253/**
244 * async_syndrome_val - asynchronously validate a raid6 syndrome 254 * async_syndrome_val - asynchronously validate a raid6 syndrome
245 * @blocks: source blocks from idx 0..disks-3, P @ disks-2 and Q @ disks-1 255 * @blocks: source blocks from idx 0..disks-3, P @ disks-2 and Q @ disks-1
@@ -260,9 +270,7 @@ async_syndrome_val(struct page **blocks, unsigned int offset, int disks,
260 size_t len, enum sum_check_flags *pqres, struct page *spare, 270 size_t len, enum sum_check_flags *pqres, struct page *spare,
261 struct async_submit_ctl *submit) 271 struct async_submit_ctl *submit)
262{ 272{
263 struct dma_chan *chan = async_tx_find_channel(submit, DMA_PQ_VAL, 273 struct dma_chan *chan = pq_val_chan(submit, blocks, disks, len);
264 NULL, 0, blocks, disks,
265 len);
266 struct dma_device *device = chan ? chan->device : NULL; 274 struct dma_device *device = chan ? chan->device : NULL;
267 struct dma_async_tx_descriptor *tx; 275 struct dma_async_tx_descriptor *tx;
268 unsigned char coefs[disks-2]; 276 unsigned char coefs[disks-2];
diff --git a/crypto/async_tx/async_xor.c b/crypto/async_tx/async_xor.c
index 79182dcb91b7..079ae8ca590b 100644
--- a/crypto/async_tx/async_xor.c
+++ b/crypto/async_tx/async_xor.c
@@ -234,6 +234,17 @@ static int page_is_zero(struct page *p, unsigned int offset, size_t len)
234 memcmp(a, a + 4, len - 4) == 0); 234 memcmp(a, a + 4, len - 4) == 0);
235} 235}
236 236
237static inline struct dma_chan *
238xor_val_chan(struct async_submit_ctl *submit, struct page *dest,
239 struct page **src_list, int src_cnt, size_t len)
240{
241 #ifdef CONFIG_ASYNC_TX_DISABLE_XOR_VAL_DMA
242 return NULL;
243 #endif
244 return async_tx_find_channel(submit, DMA_XOR_VAL, &dest, 1, src_list,
245 src_cnt, len);
246}
247
237/** 248/**
238 * async_xor_val - attempt a xor parity check with a dma engine. 249 * async_xor_val - attempt a xor parity check with a dma engine.
239 * @dest: destination page used if the xor is performed synchronously 250 * @dest: destination page used if the xor is performed synchronously
@@ -255,9 +266,7 @@ async_xor_val(struct page *dest, struct page **src_list, unsigned int offset,
255 int src_cnt, size_t len, enum sum_check_flags *result, 266 int src_cnt, size_t len, enum sum_check_flags *result,
256 struct async_submit_ctl *submit) 267 struct async_submit_ctl *submit)
257{ 268{
258 struct dma_chan *chan = async_tx_find_channel(submit, DMA_XOR_VAL, 269 struct dma_chan *chan = xor_val_chan(submit, dest, src_list, src_cnt, len);
259 &dest, 1, src_list,
260 src_cnt, len);
261 struct dma_device *device = chan ? chan->device : NULL; 270 struct dma_device *device = chan ? chan->device : NULL;
262 struct dma_async_tx_descriptor *tx = NULL; 271 struct dma_async_tx_descriptor *tx = NULL;
263 dma_addr_t *dma_src = NULL; 272 dma_addr_t *dma_src = NULL;
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 5903a88351bf..b401dadad4a8 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -26,6 +26,8 @@ config INTEL_IOATDMA
26 select DMA_ENGINE 26 select DMA_ENGINE
27 select DCA 27 select DCA
28 select ASYNC_TX_DISABLE_CHANNEL_SWITCH 28 select ASYNC_TX_DISABLE_CHANNEL_SWITCH
29 select ASYNC_TX_DISABLE_PQ_VAL_DMA
30 select ASYNC_TX_DISABLE_XOR_VAL_DMA
29 help 31 help
30 Enable support for the Intel(R) I/OAT DMA engine present 32 Enable support for the Intel(R) I/OAT DMA engine present
31 in recent Intel Xeon chipsets. 33 in recent Intel Xeon chipsets.
diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
index b6442f09d0fe..8f99354082ce 100644
--- a/drivers/dma/dmaengine.c
+++ b/drivers/dma/dmaengine.c
@@ -632,16 +632,22 @@ static bool device_has_all_tx_types(struct dma_device *device)
632 #if defined(CONFIG_ASYNC_XOR) || defined(CONFIG_ASYNC_XOR_MODULE) 632 #if defined(CONFIG_ASYNC_XOR) || defined(CONFIG_ASYNC_XOR_MODULE)
633 if (!dma_has_cap(DMA_XOR, device->cap_mask)) 633 if (!dma_has_cap(DMA_XOR, device->cap_mask))
634 return false; 634 return false;
635
636 #ifndef CONFIG_ASYNC_TX_DISABLE_XOR_VAL_DMA
635 if (!dma_has_cap(DMA_XOR_VAL, device->cap_mask)) 637 if (!dma_has_cap(DMA_XOR_VAL, device->cap_mask))
636 return false; 638 return false;
637 #endif 639 #endif
640 #endif
638 641
639 #if defined(CONFIG_ASYNC_PQ) || defined(CONFIG_ASYNC_PQ_MODULE) 642 #if defined(CONFIG_ASYNC_PQ) || defined(CONFIG_ASYNC_PQ_MODULE)
640 if (!dma_has_cap(DMA_PQ, device->cap_mask)) 643 if (!dma_has_cap(DMA_PQ, device->cap_mask))
641 return false; 644 return false;
645
646 #ifndef CONFIG_ASYNC_TX_DISABLE_PQ_VAL_DMA
642 if (!dma_has_cap(DMA_PQ_VAL, device->cap_mask)) 647 if (!dma_has_cap(DMA_PQ_VAL, device->cap_mask))
643 return false; 648 return false;
644 #endif 649 #endif
650 #endif
645 651
646 return true; 652 return true;
647} 653}
diff --git a/drivers/dma/ioat/dma_v3.c b/drivers/dma/ioat/dma_v3.c
index 252cf2d3f1da..189788f6351e 100644
--- a/drivers/dma/ioat/dma_v3.c
+++ b/drivers/dma/ioat/dma_v3.c
@@ -1206,6 +1206,16 @@ int __devinit ioat3_dma_probe(struct ioatdma_device *device, int dca)
1206 device->timer_fn = ioat2_timer_event; 1206 device->timer_fn = ioat2_timer_event;
1207 } 1207 }
1208 1208
1209 #ifdef CONFIG_ASYNC_TX_DISABLE_PQ_VAL_DMA
1210 dma_cap_clear(DMA_PQ_VAL, dma->cap_mask);
1211 dma->device_prep_dma_pq_val = NULL;
1212 #endif
1213
1214 #ifdef CONFIG_ASYNC_TX_DISABLE_XOR_VAL_DMA
1215 dma_cap_clear(DMA_XOR_VAL, dma->cap_mask);
1216 dma->device_prep_dma_xor_val = NULL;
1217 #endif
1218
1209 /* -= IOAT ver.3 workarounds =- */ 1219 /* -= IOAT ver.3 workarounds =- */
1210 /* Write CHANERRMSK_INT with 3E07h to mask out the errors 1220 /* Write CHANERRMSK_INT with 3E07h to mask out the errors
1211 * that can cause stability issues for IOAT ver.3 1221 * that can cause stability issues for IOAT ver.3