diff options
author | Dan Williams <dan.j.williams@intel.com> | 2009-11-19 19:10:37 -0500 |
---|---|---|
committer | Dan Williams <dan.j.williams@intel.com> | 2009-11-20 01:21:03 -0500 |
commit | 7b3cc2b1fc2066391e498f3387204908c4eced21 (patch) | |
tree | 8a2bc28955710c580201046d04843773cb7d87a1 | |
parent | 4499a24dec00e037da7d09caccad45e7594a9c19 (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/Kconfig | 5 | ||||
-rw-r--r-- | crypto/async_tx/async_pq.c | 14 | ||||
-rw-r--r-- | crypto/async_tx/async_xor.c | 15 | ||||
-rw-r--r-- | drivers/dma/Kconfig | 2 | ||||
-rw-r--r-- | drivers/dma/dmaengine.c | 6 | ||||
-rw-r--r-- | drivers/dma/ioat/dma_v3.c | 10 |
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 | ||
26 | config ASYNC_TX_DISABLE_PQ_VAL_DMA | ||
27 | bool | ||
28 | |||
29 | config 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 | } |
241 | EXPORT_SYMBOL_GPL(async_gen_syndrome); | 241 | EXPORT_SYMBOL_GPL(async_gen_syndrome); |
242 | 242 | ||
243 | static inline struct dma_chan * | ||
244 | pq_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 | ||
237 | static inline struct dma_chan * | ||
238 | xor_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 |