Skip to contentSkip to conversation

async_tx: PQXOR implementation

PATCH In review Yuri Tikhonov 2 participants 2 messages Dec 4, 2007 – Dec 28, 2007

Subsystems (4)
lore
Share & tools
lore
#0 lore raw

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
index d8fb391..b1705d1 100644
@@ -14,3 +14,7 @@ config ASYNC_MEMSET
 	tristate
 	select ASYNC_CORE
 
+config ASYNC_PQXOR
+	tristate
+	select ASYNC_CORE
+
crypto/async_tx/Makefile +1 -0
index 27baa7d..32d6ce2 100644
@@ -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
index bdca3f1..80bf0a3 100644
@@ -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
index a3b6035..50d1ae3 100644
@@ -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
#1 lore raw
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 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.

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