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>
This commit is contained in:
@@ -23,3 +23,8 @@ config ASYNC_RAID6_RECOV
|
||||
select ASYNC_CORE
|
||||
select ASYNC_PQ
|
||||
|
||||
config ASYNC_TX_DISABLE_PQ_VAL_DMA
|
||||
bool
|
||||
|
||||
config ASYNC_TX_DISABLE_XOR_VAL_DMA
|
||||
bool
|
||||
|
@@ -240,6 +240,16 @@ async_gen_syndrome(struct page **blocks, unsigned int offset, int disks,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(async_gen_syndrome);
|
||||
|
||||
static inline struct dma_chan *
|
||||
pq_val_chan(struct async_submit_ctl *submit, struct page **blocks, int disks, size_t len)
|
||||
{
|
||||
#ifdef CONFIG_ASYNC_TX_DISABLE_PQ_VAL_DMA
|
||||
return NULL;
|
||||
#endif
|
||||
return async_tx_find_channel(submit, DMA_PQ_VAL, NULL, 0, blocks,
|
||||
disks, len);
|
||||
}
|
||||
|
||||
/**
|
||||
* async_syndrome_val - asynchronously validate a raid6 syndrome
|
||||
* @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,
|
||||
size_t len, enum sum_check_flags *pqres, struct page *spare,
|
||||
struct async_submit_ctl *submit)
|
||||
{
|
||||
struct dma_chan *chan = async_tx_find_channel(submit, DMA_PQ_VAL,
|
||||
NULL, 0, blocks, disks,
|
||||
len);
|
||||
struct dma_chan *chan = pq_val_chan(submit, blocks, disks, len);
|
||||
struct dma_device *device = chan ? chan->device : NULL;
|
||||
struct dma_async_tx_descriptor *tx;
|
||||
unsigned char coefs[disks-2];
|
||||
|
@@ -234,6 +234,17 @@ static int page_is_zero(struct page *p, unsigned int offset, size_t len)
|
||||
memcmp(a, a + 4, len - 4) == 0);
|
||||
}
|
||||
|
||||
static inline struct dma_chan *
|
||||
xor_val_chan(struct async_submit_ctl *submit, struct page *dest,
|
||||
struct page **src_list, int src_cnt, size_t len)
|
||||
{
|
||||
#ifdef CONFIG_ASYNC_TX_DISABLE_XOR_VAL_DMA
|
||||
return NULL;
|
||||
#endif
|
||||
return async_tx_find_channel(submit, DMA_XOR_VAL, &dest, 1, src_list,
|
||||
src_cnt, len);
|
||||
}
|
||||
|
||||
/**
|
||||
* async_xor_val - attempt a xor parity check with a dma engine.
|
||||
* @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,
|
||||
int src_cnt, size_t len, enum sum_check_flags *result,
|
||||
struct async_submit_ctl *submit)
|
||||
{
|
||||
struct dma_chan *chan = async_tx_find_channel(submit, DMA_XOR_VAL,
|
||||
&dest, 1, src_list,
|
||||
src_cnt, len);
|
||||
struct dma_chan *chan = xor_val_chan(submit, dest, src_list, src_cnt, len);
|
||||
struct dma_device *device = chan ? chan->device : NULL;
|
||||
struct dma_async_tx_descriptor *tx = NULL;
|
||||
dma_addr_t *dma_src = NULL;
|
||||
|
Reference in New Issue
Block a user