diff options
author | Dan Williams <dan.j.williams@intel.com> | 2013-11-13 13:37:36 -0500 |
---|---|---|
committer | Dan Williams <dan.j.williams@intel.com> | 2013-11-14 14:04:41 -0500 |
commit | 21e96c7313486390c694919522a76dfea0a86c59 (patch) | |
tree | 211439af0431a256def810a915e37ee6519ae4a6 /drivers/dma/ioat | |
parent | 5d48b9b5d80e3aa38a5161565398b1e48a650573 (diff) |
ioatdma: fix selection of 16 vs 8 source path
When performing continuations there are implied sources that need to be
added to the source count. Quoting dma_set_maxpq:
/* dma_maxpq - reduce maxpq in the face of continued operations
* @dma - dma device with PQ capability
* @flags - to check if DMA_PREP_CONTINUE and DMA_PREP_PQ_DISABLE_P are set
*
* When an engine does not support native continuation we need 3 extra
* source slots to reuse P and Q with the following coefficients:
* 1/ {00} * P : remove P from Q', but use it as a source for P'
* 2/ {01} * Q : use Q to continue Q' calculation
* 3/ {00} * Q : subtract Q from P' to cancel (2)
*
* In the case where P is disabled we only need 1 extra source:
* 1/ {01} * Q : use Q to continue Q' calculation
*/
...fix the selection of the 16 source path to take these implied sources
into account.
Note this also kills the BUG_ON(src_cnt < 9) check in
__ioat3_prep_pq16_lock(). Besides not accounting for implied sources
the check is redundant given we already made the path selection.
Cc: <stable@vger.kernel.org>
Cc: Dave Jiang <dave.jiang@intel.com>
Acked-by: Dave Jiang <dave.jiang@intel.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Diffstat (limited to 'drivers/dma/ioat')
-rw-r--r-- | drivers/dma/ioat/dma_v3.c | 30 |
1 files changed, 15 insertions, 15 deletions
diff --git a/drivers/dma/ioat/dma_v3.c b/drivers/dma/ioat/dma_v3.c index f26a35d43ba1..0284908997f8 100644 --- a/drivers/dma/ioat/dma_v3.c +++ b/drivers/dma/ioat/dma_v3.c | |||
@@ -951,9 +951,6 @@ __ioat3_prep_pq16_lock(struct dma_chan *c, enum sum_check_flags *result, | |||
951 | u8 op; | 951 | u8 op; |
952 | int i, s, idx, num_descs; | 952 | int i, s, idx, num_descs; |
953 | 953 | ||
954 | /* this function only handles src_cnt 9 - 16 */ | ||
955 | BUG_ON(src_cnt < 9); | ||
956 | |||
957 | /* this function is only called with 9-16 sources */ | 954 | /* this function is only called with 9-16 sources */ |
958 | op = result ? IOAT_OP_PQ_VAL_16S : IOAT_OP_PQ_16S; | 955 | op = result ? IOAT_OP_PQ_VAL_16S : IOAT_OP_PQ_16S; |
959 | 956 | ||
@@ -1039,13 +1036,21 @@ __ioat3_prep_pq16_lock(struct dma_chan *c, enum sum_check_flags *result, | |||
1039 | return &desc->txd; | 1036 | return &desc->txd; |
1040 | } | 1037 | } |
1041 | 1038 | ||
1039 | static int src_cnt_flags(unsigned int src_cnt, unsigned long flags) | ||
1040 | { | ||
1041 | if (dmaf_p_disabled_continue(flags)) | ||
1042 | return src_cnt + 1; | ||
1043 | else if (dmaf_continue(flags)) | ||
1044 | return src_cnt + 3; | ||
1045 | else | ||
1046 | return src_cnt; | ||
1047 | } | ||
1048 | |||
1042 | static struct dma_async_tx_descriptor * | 1049 | static struct dma_async_tx_descriptor * |
1043 | ioat3_prep_pq(struct dma_chan *chan, dma_addr_t *dst, dma_addr_t *src, | 1050 | ioat3_prep_pq(struct dma_chan *chan, dma_addr_t *dst, dma_addr_t *src, |
1044 | unsigned int src_cnt, const unsigned char *scf, size_t len, | 1051 | unsigned int src_cnt, const unsigned char *scf, size_t len, |
1045 | unsigned long flags) | 1052 | unsigned long flags) |
1046 | { | 1053 | { |
1047 | struct dma_device *dma = chan->device; | ||
1048 | |||
1049 | /* specify valid address for disabled result */ | 1054 | /* specify valid address for disabled result */ |
1050 | if (flags & DMA_PREP_PQ_DISABLE_P) | 1055 | if (flags & DMA_PREP_PQ_DISABLE_P) |
1051 | dst[0] = dst[1]; | 1056 | dst[0] = dst[1]; |
@@ -1065,7 +1070,7 @@ ioat3_prep_pq(struct dma_chan *chan, dma_addr_t *dst, dma_addr_t *src, | |||
1065 | single_source_coef[0] = scf[0]; | 1070 | single_source_coef[0] = scf[0]; |
1066 | single_source_coef[1] = 0; | 1071 | single_source_coef[1] = 0; |
1067 | 1072 | ||
1068 | return (src_cnt > 8) && (dma->max_pq > 8) ? | 1073 | return src_cnt_flags(src_cnt, flags) > 8 ? |
1069 | __ioat3_prep_pq16_lock(chan, NULL, dst, single_source, | 1074 | __ioat3_prep_pq16_lock(chan, NULL, dst, single_source, |
1070 | 2, single_source_coef, len, | 1075 | 2, single_source_coef, len, |
1071 | flags) : | 1076 | flags) : |
@@ -1073,7 +1078,7 @@ ioat3_prep_pq(struct dma_chan *chan, dma_addr_t *dst, dma_addr_t *src, | |||
1073 | single_source_coef, len, flags); | 1078 | single_source_coef, len, flags); |
1074 | 1079 | ||
1075 | } else { | 1080 | } else { |
1076 | return (src_cnt > 8) && (dma->max_pq > 8) ? | 1081 | return src_cnt_flags(src_cnt, flags) > 8 ? |
1077 | __ioat3_prep_pq16_lock(chan, NULL, dst, src, src_cnt, | 1082 | __ioat3_prep_pq16_lock(chan, NULL, dst, src, src_cnt, |
1078 | scf, len, flags) : | 1083 | scf, len, flags) : |
1079 | __ioat3_prep_pq_lock(chan, NULL, dst, src, src_cnt, | 1084 | __ioat3_prep_pq_lock(chan, NULL, dst, src, src_cnt, |
@@ -1086,8 +1091,6 @@ ioat3_prep_pq_val(struct dma_chan *chan, dma_addr_t *pq, dma_addr_t *src, | |||
1086 | unsigned int src_cnt, const unsigned char *scf, size_t len, | 1091 | unsigned int src_cnt, const unsigned char *scf, size_t len, |
1087 | enum sum_check_flags *pqres, unsigned long flags) | 1092 | enum sum_check_flags *pqres, unsigned long flags) |
1088 | { | 1093 | { |
1089 | struct dma_device *dma = chan->device; | ||
1090 | |||
1091 | /* specify valid address for disabled result */ | 1094 | /* specify valid address for disabled result */ |
1092 | if (flags & DMA_PREP_PQ_DISABLE_P) | 1095 | if (flags & DMA_PREP_PQ_DISABLE_P) |
1093 | pq[0] = pq[1]; | 1096 | pq[0] = pq[1]; |
@@ -1099,7 +1102,7 @@ ioat3_prep_pq_val(struct dma_chan *chan, dma_addr_t *pq, dma_addr_t *src, | |||
1099 | */ | 1102 | */ |
1100 | *pqres = 0; | 1103 | *pqres = 0; |
1101 | 1104 | ||
1102 | return (src_cnt > 8) && (dma->max_pq > 8) ? | 1105 | return src_cnt_flags(src_cnt, flags) > 8 ? |
1103 | __ioat3_prep_pq16_lock(chan, pqres, pq, src, src_cnt, scf, len, | 1106 | __ioat3_prep_pq16_lock(chan, pqres, pq, src, src_cnt, scf, len, |
1104 | flags) : | 1107 | flags) : |
1105 | __ioat3_prep_pq_lock(chan, pqres, pq, src, src_cnt, scf, len, | 1108 | __ioat3_prep_pq_lock(chan, pqres, pq, src, src_cnt, scf, len, |
@@ -1110,7 +1113,6 @@ static struct dma_async_tx_descriptor * | |||
1110 | ioat3_prep_pqxor(struct dma_chan *chan, dma_addr_t dst, dma_addr_t *src, | 1113 | ioat3_prep_pqxor(struct dma_chan *chan, dma_addr_t dst, dma_addr_t *src, |
1111 | unsigned int src_cnt, size_t len, unsigned long flags) | 1114 | unsigned int src_cnt, size_t len, unsigned long flags) |
1112 | { | 1115 | { |
1113 | struct dma_device *dma = chan->device; | ||
1114 | unsigned char scf[src_cnt]; | 1116 | unsigned char scf[src_cnt]; |
1115 | dma_addr_t pq[2]; | 1117 | dma_addr_t pq[2]; |
1116 | 1118 | ||
@@ -1119,7 +1121,7 @@ ioat3_prep_pqxor(struct dma_chan *chan, dma_addr_t dst, dma_addr_t *src, | |||
1119 | flags |= DMA_PREP_PQ_DISABLE_Q; | 1121 | flags |= DMA_PREP_PQ_DISABLE_Q; |
1120 | pq[1] = dst; /* specify valid address for disabled result */ | 1122 | pq[1] = dst; /* specify valid address for disabled result */ |
1121 | 1123 | ||
1122 | return (src_cnt > 8) && (dma->max_pq > 8) ? | 1124 | return src_cnt_flags(src_cnt, flags) > 8 ? |
1123 | __ioat3_prep_pq16_lock(chan, NULL, pq, src, src_cnt, scf, len, | 1125 | __ioat3_prep_pq16_lock(chan, NULL, pq, src, src_cnt, scf, len, |
1124 | flags) : | 1126 | flags) : |
1125 | __ioat3_prep_pq_lock(chan, NULL, pq, src, src_cnt, scf, len, | 1127 | __ioat3_prep_pq_lock(chan, NULL, pq, src, src_cnt, scf, len, |
@@ -1131,7 +1133,6 @@ ioat3_prep_pqxor_val(struct dma_chan *chan, dma_addr_t *src, | |||
1131 | unsigned int src_cnt, size_t len, | 1133 | unsigned int src_cnt, size_t len, |
1132 | enum sum_check_flags *result, unsigned long flags) | 1134 | enum sum_check_flags *result, unsigned long flags) |
1133 | { | 1135 | { |
1134 | struct dma_device *dma = chan->device; | ||
1135 | unsigned char scf[src_cnt]; | 1136 | unsigned char scf[src_cnt]; |
1136 | dma_addr_t pq[2]; | 1137 | dma_addr_t pq[2]; |
1137 | 1138 | ||
@@ -1145,8 +1146,7 @@ ioat3_prep_pqxor_val(struct dma_chan *chan, dma_addr_t *src, | |||
1145 | flags |= DMA_PREP_PQ_DISABLE_Q; | 1146 | flags |= DMA_PREP_PQ_DISABLE_Q; |
1146 | pq[1] = pq[0]; /* specify valid address for disabled result */ | 1147 | pq[1] = pq[0]; /* specify valid address for disabled result */ |
1147 | 1148 | ||
1148 | 1149 | return src_cnt_flags(src_cnt, flags) > 8 ? | |
1149 | return (src_cnt > 8) && (dma->max_pq > 8) ? | ||
1150 | __ioat3_prep_pq16_lock(chan, result, pq, &src[1], src_cnt - 1, | 1150 | __ioat3_prep_pq16_lock(chan, result, pq, &src[1], src_cnt - 1, |
1151 | scf, len, flags) : | 1151 | scf, len, flags) : |
1152 | __ioat3_prep_pq_lock(chan, result, pq, &src[1], src_cnt - 1, | 1152 | __ioat3_prep_pq_lock(chan, result, pq, &src[1], src_cnt - 1, |