async_tx: PQXOR implementation
PATCH 1/12 async_tx: PQXOR implementation
This patch implements support for the asynchronous computation of RAID-6
syndromes.
It provides an API to compute RAID-6 syndromes asynchronously in a format
conforming to async_tx interfaces. The async_pxor and async_pqxor_zero_sum functions are very similar to async_xor functions but make use of additional tx_set_src_mult method for setting cooefficients of the RAID-6 Q syndrome.
The Galois polynomial which is used in the s/w case is 0x11d (the
corresponding coefficients are hard-coded in raid6_call.gen_syndrome). Because even with the h/w acceleration enabled some pqxor operations may be processed in CPU (e.g. in case of no DMA descriptors available) it's highly recommended to configure the DMA engine which your system uses to exploit exactly the same Galois polynomial.
--
crypto/async_tx/Kconfig +4 -0
@@ -14,3 +14,7 @@ config ASYNC_MEMSET tristate select ASYNC_CORE +config ASYNC_PQXOR + tristate + select ASYNC_CORE +
crypto/async_tx/Makefile +1 -0
@@ -2,3 +2,4 @@ obj-$(CONFIG_ASYNC_CORE) += async_tx.o obj-$(CONFIG_ASYNC_MEMCPY) += async_memcpy.o obj-$(CONFIG_ASYNC_MEMSET) += async_memset.o obj-$(CONFIG_ASYNC_XOR) += async_xor.o +obj-$(CONFIG_ASYNC_PQXOR) += async_pqxor.o
crypto/async_tx/async_pqxor.c new file +331 -0
331 lines not on this page · raw message
include/linux/async_tx.h +19 -0
@@ -51,6 +51,8 @@ struct dma_chan_ref {* @ASYNC_TX_ACK: immediately ack the descriptor, precludes setting up a * dependency chain * @ASYNC_TX_DEP_ACK: ack the dependency descriptor. Useful for chaining. +* @ASYNC_TX_ASYNC_ONLY: if set then try to perform operation requested in +* asynchronous way only. */ enum async_tx_flags {ASYNC_TX_XOR_ZERO_DST = (1 <<0 ),
@@ -58,6 +60,7 @@ enum async_tx_flags {ASYNC_TX_ASSUME_COHERENT = (1 <<2 ),ASYNC_TX_ACK = (1 <<3 ),ASYNC_TX_DEP_ACK = (1 <<4 ), + ASYNC_TX_ASYNC_ONLY = (1 << 7), };#ifdef CONFIG_DMA_ENGINE
@@ -147,4 +150,20 @@ struct dma_async_tx_descriptor * async_trigger_callback(enum async_tx_flags flags, struct dma_async_tx_descriptor *depend_tx, dma_async_tx_callback cb_fn, void *cb_fn_param); + +struct dma_async_tx_descriptor * +async_pqxor (struct page *pdest,struct page *qdest, +struct page **src_list,unsigned char *scoef_list, +unsigned int offset,int src_cnt,size_t len,enum async_tx_flags flags, +struct dma_async_tx_descriptor *depend_tx, +dma_async_tx_callback callback,void *callback_param); + +struct dma_async_tx_descriptor * +async_pqxor_zero_sum (struct page *pdest,struct page *qdest, +struct page **src_list,unsigned char *scoef_list, +unsigned int offset,int src_cnt,size_t len, +u32 *presult,u32 *qresult,enum async_tx_flags flags, +struct dma_async_tx_descriptor *depend_tx, +dma_async_tx_callback callback,void *callback_param); +#endif /* _ASYNC_TX_H_ */
include/linux/dmaengine.h +13 -0
@@ -210,6 +210,7 @@ typedef void (*dma_async_tx_callback)(void *dma_async_param);* @tx_submit: set the prepared descriptor(s) to be executed by the engine * @tx_set_dest: set a destination address in a hardware descriptor * @tx_set_src: set a source address in a hardware descriptor +* @tx_set_src_mult: set a GF-multiplier in a hardware descriptor * @callback: routine to call after this operation is complete * @callback_param: general parameter to pass to the callback routine * ---async_tx api specific fields---
@@ -230,6 +231,8 @@ struct dma_async_tx_descriptor { struct dma_async_tx_descriptor *tx, int index);void (*tx_set_src)(dma_addr_t addr,struct dma_async_tx_descriptor *tx,int index); +void (*tx_set_src_mult)(unsigned char mult, +struct dma_async_tx_descriptor *tx,int index);dma_async_tx_callback callback;void *callback_param;struct list_head depend_list;
@@ -254,7 +257,9 @@ struct dma_async_tx_descriptor {* @device_free_chan_resources: release DMA channel's resources * @device_prep_dma_memcpy: prepares a memcpy operation * @device_prep_dma_xor: prepares a xor operation +* @device_prep_dma_pqxor: prepares a pq-xor operation * @device_prep_dma_zero_sum: prepares a zero_sum operation +* @device_prep_dma_pqzero_sum: prepares a pqzero_sum operation * @device_prep_dma_memset: prepares a memset operation * @device_prep_dma_interrupt: prepares an end of chain interrupt operation * @device_dependency_added: async_tx notifies the channel about new deps
@@ -282,9 +287,17 @@ struct dma_device {struct dma_async_tx_descriptor *(*device_prep_dma_xor)(struct dma_chan *chan,unsigned int src_cnt,size_t len,int int_en); +struct dma_async_tx_descriptor *(*device_prep_dma_pqxor)( +struct dma_chan *chan,struct page **sas, +unsigned int src_cnt,unsigned int dst_cnt, +size_t len,int zero_dst,int int_en);struct dma_async_tx_descriptor *(*device_prep_dma_zero_sum)(struct dma_chan *chan,unsigned int src_cnt,size_t len,u32 *result,int int_en); +struct dma_async_tx_descriptor *(*device_prep_dma_pqzero_sum)( +struct dma_chan *chan, +unsigned int src_cnt,unsigned int dst_cnt,size_t len, +u32 *presult,u32 *qresult,int int_en);struct dma_async_tx_descriptor *(*device_prep_dma_memset)(struct dma_chan *chan,int value,size_t len,int int_en); struct dma_async_tx_descriptor *(*device_prep_dma_interrupt)(
Signature · 2 lines
Yuri Tikhonov, Senior Software Engineer Emcraft Systems, www.emcraft.com
Quoted 9 lines · Yuri Tikhonov
This patch implements support for the asynchronous computation of RAID-6
syndromes.It provides an API to compute RAID-6 syndromes asynchronously in a format
conforming toasync_txinterfaces. Theasync_pxorandasync_pqxor_zero_sumfunctions are very similar toasync_xorfunctions but make use of additionaltx_set_src_multmethod for setting cooefficients of the RAID-6 Q syndrome.
Quoted 7 lines
The Galois polynomial which is used in the s/w case is
0x11d(the
corresponding coefficients are hard-coded in raid6_call.gen_syndrome). Because even with the h/w acceleration enabled some pqxor operations may be processed in CPU (e.g. in case of no DMA descriptors available) it's highly recommended to configure the DMA engine which your system uses to exploit exactly the same Galois polynomial.
It should probably be noted here, too, that if you use a different basis polynomial for the Galois field you will end up with a different on-disk format.
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
This address, I believe, is obsolete.
+ if (!(tx=async_pqxor(NULL, ptrs[failb],
+ &ptrs[disks - 2], bc, 0, 2, bytes,
+ ASYNC_TX_DEP_ACK | ASYNC_TX_XOR_ZERO_DST,
+ tx, NULL, NULL))) {
+ /* It's bad if we failed here; try to repeat this
+ * using another failed disk as a spare; this wouldn't
+ * failed since now we'll be able to compute synchronously
+ * (there is no support for synchronous Q-only)
+ */
+ async_pqxor(ptrs[faila], ptrs[failb],
+ &ptrs[disks - 2], bc, 0, 2, bytes,
+ ASYNC_TX_DEP_ACK | ASYNC_TX_XOR_ZERO_DST,
+ NULL, NULL, NULL);
+ }
I don't really understand this logic, or the comment that goes along with it. Could you please elucidate?
-hpa