]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
RDMA/siw: Switch to using the crc32c library
authorEric Biggers <ebiggers@google.com>
Thu, 27 Feb 2025 05:12:07 +0000 (21:12 -0800)
committerLeon Romanovsky <leon@kernel.org>
Mon, 3 Mar 2025 12:14:33 +0000 (07:14 -0500)
Now that the crc32c() library function directly takes advantage of
architecture-specific optimizations, it is unnecessary to go through the
crypto API.  Just use crc32c().  This is much simpler, and it improves
performance due to eliminating the crypto API overhead.

Signed-off-by: Eric Biggers <ebiggers@google.com>
Link: https://patch.msgid.link/20250227051207.19470-1-ebiggers@kernel.org
Acked-by: Bernard Metzler <bmt@zurich.ibm.com>
Signed-off-by: Leon Romanovsky <leon@kernel.org>
drivers/infiniband/sw/siw/Kconfig
drivers/infiniband/sw/siw/siw.h
drivers/infiniband/sw/siw/siw_main.c
drivers/infiniband/sw/siw/siw_qp.c
drivers/infiniband/sw/siw/siw_qp_rx.c
drivers/infiniband/sw/siw/siw_qp_tx.c
drivers/infiniband/sw/siw/siw_verbs.c

index 81b70a3eeb87821a8cac4393939ae06f5e41e078..ae4a953e2a039de8fdc8bd90f6c2fba38622412d 100644 (file)
@@ -2,9 +2,7 @@ config RDMA_SIW
        tristate "Software RDMA over TCP/IP (iWARP) driver"
        depends on INET && INFINIBAND
        depends on INFINIBAND_VIRT_DMA
-       select LIBCRC32C
-       select CRYPTO
-       select CRYPTO_CRC32C
+       select CRC32
        help
        This driver implements the iWARP RDMA transport over
        the Linux TCP/IP network stack. It enables a system with a
index ea5eee50dc39d05886a99f8af2bd4189e0dab485..21238746716a94506d871d114f1b63eb1c4770c0 100644 (file)
@@ -10,9 +10,9 @@
 #include <rdma/restrack.h>
 #include <linux/socket.h>
 #include <linux/skbuff.h>
-#include <crypto/hash.h>
 #include <linux/crc32.h>
 #include <linux/crc32c.h>
+#include <linux/unaligned.h>
 
 #include <rdma/siw-abi.h>
 #include "iwarp.h"
@@ -289,7 +289,8 @@ struct siw_rx_stream {
 
        union iwarp_hdr hdr;
        struct mpa_trailer trailer;
-       struct shash_desc *mpa_crc_hd;
+       u32 mpa_crc;
+       bool mpa_crc_enabled;
 
        /*
         * For each FPDU, main RX loop runs through 3 stages:
@@ -390,7 +391,8 @@ struct siw_iwarp_tx {
        int burst;
        int bytes_unsent; /* ddp payload bytes */
 
-       struct shash_desc *mpa_crc_hd;
+       u32 mpa_crc;
+       bool mpa_crc_enabled;
 
        u8 do_crc : 1; /* do crc for segment */
        u8 use_sendpage : 1; /* send w/o copy */
@@ -496,7 +498,6 @@ extern u_char mpa_version;
 extern const bool peer_to_peer;
 extern struct task_struct *siw_tx_thread[];
 
-extern struct crypto_shash *siw_crypto_shash;
 extern struct iwarp_msg_info iwarp_pktinfo[RDMAP_TERMINATE + 1];
 
 /* QP general functions */
@@ -668,6 +669,30 @@ static inline struct siw_sqe *irq_alloc_free(struct siw_qp *qp)
        return NULL;
 }
 
+static inline void siw_crc_init(u32 *crc)
+{
+       *crc = ~0;
+}
+
+static inline void siw_crc_update(u32 *crc, const void *data, size_t len)
+{
+       *crc = crc32c(*crc, data, len);
+}
+
+static inline void siw_crc_final(u32 *crc, u8 out[4])
+{
+       put_unaligned_le32(~*crc, out);
+}
+
+static inline void siw_crc_oneshot(const void *data, size_t len, u8 out[4])
+{
+       u32 crc;
+
+       siw_crc_init(&crc);
+       siw_crc_update(&crc, data, len);
+       return siw_crc_final(&crc, out);
+}
+
 static inline __wsum siw_csum_update(const void *buff, int len, __wsum sum)
 {
        return (__force __wsum)crc32c((__force __u32)sum, buff, len);
@@ -686,11 +711,11 @@ static inline void siw_crc_skb(struct siw_rx_stream *srx, unsigned int len)
                .update = siw_csum_update,
                .combine = siw_csum_combine,
        };
-       __wsum crc = *(u32 *)shash_desc_ctx(srx->mpa_crc_hd);
+       __wsum crc = (__force __wsum)srx->mpa_crc;
 
        crc = __skb_checksum(srx->skb, srx->skb_offset, len, crc,
                             &siw_cs_ops);
-       *(u32 *)shash_desc_ctx(srx->mpa_crc_hd) = crc;
+       srx->mpa_crc = (__force u32)crc;
 }
 
 #define siw_dbg(ibdev, fmt, ...)                                               \
index b17752bd1ecc180907c675ec62e7654e8606e441..5168307229a9e07695f85231a02d29a403535936 100644 (file)
@@ -59,7 +59,6 @@ u_char mpa_version = MPA_REVISION_2;
 const bool peer_to_peer;
 
 struct task_struct *siw_tx_thread[NR_CPUS];
-struct crypto_shash *siw_crypto_shash;
 
 static int siw_device_register(struct siw_device *sdev, const char *name)
 {
@@ -467,20 +466,7 @@ static __init int siw_init_module(void)
                rv = -ENOMEM;
                goto out_error;
        }
-       /*
-        * Locate CRC32 algorithm. If unsuccessful, fail
-        * loading siw only, if CRC is required.
-        */
-       siw_crypto_shash = crypto_alloc_shash("crc32c", 0, 0);
-       if (IS_ERR(siw_crypto_shash)) {
-               pr_info("siw: Loading CRC32c failed: %ld\n",
-                       PTR_ERR(siw_crypto_shash));
-               siw_crypto_shash = NULL;
-               if (mpa_crc_required) {
-                       rv = -EOPNOTSUPP;
-                       goto out_error;
-               }
-       }
+
        rv = register_netdevice_notifier(&siw_netdev_nb);
        if (rv)
                goto out_error;
@@ -493,9 +479,6 @@ static __init int siw_init_module(void)
 out_error:
        siw_stop_tx_threads();
 
-       if (siw_crypto_shash)
-               crypto_free_shash(siw_crypto_shash);
-
        pr_info("SoftIWARP attach failed. Error: %d\n", rv);
 
        siw_cm_exit();
@@ -516,9 +499,6 @@ static void __exit siw_exit_module(void)
 
        siw_destroy_cpulist(siw_cpu_info.num_nodes);
 
-       if (siw_crypto_shash)
-               crypto_free_shash(siw_crypto_shash);
-
        pr_info("SoftiWARP detached\n");
 }
 
index da92cfa2073d7605f5085954088c501292906880..c1e6e7d6e32f8ceb6539a685d9570739bba763cf 100644 (file)
@@ -226,33 +226,6 @@ static int siw_qp_readq_init(struct siw_qp *qp, int irq_size, int orq_size)
        return 0;
 }
 
-static int siw_qp_enable_crc(struct siw_qp *qp)
-{
-       struct siw_rx_stream *c_rx = &qp->rx_stream;
-       struct siw_iwarp_tx *c_tx = &qp->tx_ctx;
-       int size;
-
-       if (siw_crypto_shash == NULL)
-               return -ENOENT;
-
-       size = crypto_shash_descsize(siw_crypto_shash) +
-               sizeof(struct shash_desc);
-
-       c_tx->mpa_crc_hd = kzalloc(size, GFP_KERNEL);
-       c_rx->mpa_crc_hd = kzalloc(size, GFP_KERNEL);
-       if (!c_tx->mpa_crc_hd || !c_rx->mpa_crc_hd) {
-               kfree(c_tx->mpa_crc_hd);
-               kfree(c_rx->mpa_crc_hd);
-               c_tx->mpa_crc_hd = NULL;
-               c_rx->mpa_crc_hd = NULL;
-               return -ENOMEM;
-       }
-       c_tx->mpa_crc_hd->tfm = siw_crypto_shash;
-       c_rx->mpa_crc_hd->tfm = siw_crypto_shash;
-
-       return 0;
-}
-
 /*
  * Send a non signalled READ or WRITE to peer side as negotiated
  * with MPAv2 P2P setup protocol. The work request is only created
@@ -583,20 +556,15 @@ void siw_send_terminate(struct siw_qp *qp)
 
        term->ctrl.mpa_len =
                cpu_to_be16(len_terminate - (MPA_HDR_SIZE + MPA_CRC_SIZE));
-       if (qp->tx_ctx.mpa_crc_hd) {
-               crypto_shash_init(qp->tx_ctx.mpa_crc_hd);
-               if (crypto_shash_update(qp->tx_ctx.mpa_crc_hd,
-                                       (u8 *)iov[0].iov_base,
-                                       iov[0].iov_len))
-                       goto out;
-
+       if (qp->tx_ctx.mpa_crc_enabled) {
+               siw_crc_init(&qp->tx_ctx.mpa_crc);
+               siw_crc_update(&qp->tx_ctx.mpa_crc,
+                              iov[0].iov_base, iov[0].iov_len);
                if (num_frags == 3) {
-                       if (crypto_shash_update(qp->tx_ctx.mpa_crc_hd,
-                                               (u8 *)iov[1].iov_base,
-                                               iov[1].iov_len))
-                               goto out;
+                       siw_crc_update(&qp->tx_ctx.mpa_crc,
+                                      iov[1].iov_base, iov[1].iov_len);
                }
-               crypto_shash_final(qp->tx_ctx.mpa_crc_hd, (u8 *)&crc);
+               siw_crc_final(&qp->tx_ctx.mpa_crc, (u8 *)&crc);
        }
 
        rv = kernel_sendmsg(s, &msg, iov, num_frags, len_terminate);
@@ -604,7 +572,6 @@ void siw_send_terminate(struct siw_qp *qp)
                   rv == len_terminate ? "success" : "failure",
                   __rdmap_term_layer(term), __rdmap_term_etype(term),
                   __rdmap_term_ecode(term), rv);
-out:
        kfree(term);
        kfree(err_hdr);
 }
@@ -643,9 +610,10 @@ static int siw_qp_nextstate_from_idle(struct siw_qp *qp,
        switch (attrs->state) {
        case SIW_QP_STATE_RTS:
                if (attrs->flags & SIW_MPA_CRC) {
-                       rv = siw_qp_enable_crc(qp);
-                       if (rv)
-                               break;
+                       siw_crc_init(&qp->tx_ctx.mpa_crc);
+                       qp->tx_ctx.mpa_crc_enabled = true;
+                       siw_crc_init(&qp->rx_stream.mpa_crc);
+                       qp->rx_stream.mpa_crc_enabled = true;
                }
                if (!(mask & SIW_QP_ATTR_LLP_HANDLE)) {
                        siw_dbg_qp(qp, "no socket\n");
index ed4fc39718b496e5dd0a8a9c75ffae12ebbfb36f..32554eba1eac7c1cce2f63a8ffc2ef07e737cfc6 100644 (file)
@@ -67,10 +67,10 @@ static int siw_rx_umem(struct siw_rx_stream *srx, struct siw_umem *umem,
 
                        return -EFAULT;
                }
-               if (srx->mpa_crc_hd) {
+               if (srx->mpa_crc_enabled) {
                        if (rdma_is_kernel_res(&rx_qp(srx)->base_qp.res)) {
-                               crypto_shash_update(srx->mpa_crc_hd,
-                                       (u8 *)(dest + pg_off), bytes);
+                               siw_crc_update(&srx->mpa_crc, dest + pg_off,
+                                              bytes);
                                kunmap_atomic(dest);
                        } else {
                                kunmap_atomic(dest);
@@ -114,8 +114,8 @@ static int siw_rx_kva(struct siw_rx_stream *srx, void *kva, int len)
 
                return rv;
        }
-       if (srx->mpa_crc_hd)
-               crypto_shash_update(srx->mpa_crc_hd, (u8 *)kva, len);
+       if (srx->mpa_crc_enabled)
+               siw_crc_update(&srx->mpa_crc, kva, len);
 
        srx->skb_offset += len;
        srx->skb_copied += len;
@@ -966,16 +966,16 @@ static int siw_get_trailer(struct siw_qp *qp, struct siw_rx_stream *srx)
        if (srx->fpdu_part_rem)
                return -EAGAIN;
 
-       if (!srx->mpa_crc_hd)
+       if (!srx->mpa_crc_enabled)
                return 0;
 
        if (srx->pad)
-               crypto_shash_update(srx->mpa_crc_hd, tbuf, srx->pad);
+               siw_crc_update(&srx->mpa_crc, tbuf, srx->pad);
        /*
         * CRC32 is computed, transmitted and received directly in NBO,
         * so there's never a reason to convert byte order.
         */
-       crypto_shash_final(srx->mpa_crc_hd, (u8 *)&crc_own);
+       siw_crc_final(&srx->mpa_crc, (u8 *)&crc_own);
        crc_in = (__force __wsum)srx->trailer.crc;
 
        if (unlikely(crc_in != crc_own)) {
@@ -1093,13 +1093,12 @@ static int siw_get_hdr(struct siw_rx_stream *srx)
         * (tagged/untagged). E.g., a WRITE can get intersected by a SEND,
         * but not by a READ RESPONSE etc.
         */
-       if (srx->mpa_crc_hd) {
+       if (srx->mpa_crc_enabled) {
                /*
                 * Restart CRC computation
                 */
-               crypto_shash_init(srx->mpa_crc_hd);
-               crypto_shash_update(srx->mpa_crc_hd, (u8 *)c_hdr,
-                                   srx->fpdu_part_rcvd);
+               siw_crc_init(&srx->mpa_crc);
+               siw_crc_update(&srx->mpa_crc, c_hdr, srx->fpdu_part_rcvd);
        }
        if (frx->more_ddp_segs) {
                frx->first_ddp_seg = 0;
index a034264c566986f751366aeee4c60f2c43bafa09..6432bce7d08317d5ef6dd7b984058c4d777c516e 100644 (file)
@@ -248,10 +248,8 @@ static int siw_qp_prepare_tx(struct siw_iwarp_tx *c_tx)
                /*
                 * Do complete CRC if enabled and short packet
                 */
-               if (c_tx->mpa_crc_hd &&
-                   crypto_shash_digest(c_tx->mpa_crc_hd, (u8 *)&c_tx->pkt,
-                                       c_tx->ctrl_len, (u8 *)crc) != 0)
-                       return -EINVAL;
+               if (c_tx->mpa_crc_enabled)
+                       siw_crc_oneshot(&c_tx->pkt, c_tx->ctrl_len, (u8 *)crc);
                c_tx->ctrl_len += MPA_CRC_SIZE;
 
                return PKT_COMPLETE;
@@ -482,9 +480,8 @@ static int siw_tx_hdt(struct siw_iwarp_tx *c_tx, struct socket *s)
                        iov[seg].iov_len = sge_len;
 
                        if (do_crc)
-                               crypto_shash_update(c_tx->mpa_crc_hd,
-                                                   iov[seg].iov_base,
-                                                   sge_len);
+                               siw_crc_update(&c_tx->mpa_crc,
+                                              iov[seg].iov_base, sge_len);
                        sge_off += sge_len;
                        data_len -= sge_len;
                        seg++;
@@ -516,15 +513,14 @@ static int siw_tx_hdt(struct siw_iwarp_tx *c_tx, struct socket *s)
                                        iov[seg].iov_len = plen;
 
                                        if (do_crc)
-                                               crypto_shash_update(
-                                                       c_tx->mpa_crc_hd,
+                                               siw_crc_update(
+                                                       &c_tx->mpa_crc,
                                                        iov[seg].iov_base,
                                                        plen);
                                } else if (do_crc) {
                                        kaddr = kmap_local_page(p);
-                                       crypto_shash_update(c_tx->mpa_crc_hd,
-                                                           kaddr + fp_off,
-                                                           plen);
+                                       siw_crc_update(&c_tx->mpa_crc,
+                                                      kaddr + fp_off, plen);
                                        kunmap_local(kaddr);
                                }
                        } else {
@@ -536,10 +532,9 @@ static int siw_tx_hdt(struct siw_iwarp_tx *c_tx, struct socket *s)
 
                                page_array[seg] = ib_virt_dma_to_page(va);
                                if (do_crc)
-                                       crypto_shash_update(
-                                               c_tx->mpa_crc_hd,
-                                               ib_virt_dma_to_ptr(va),
-                                               plen);
+                                       siw_crc_update(&c_tx->mpa_crc,
+                                                      ib_virt_dma_to_ptr(va),
+                                                      plen);
                        }
 
                        sge_len -= plen;
@@ -576,14 +571,14 @@ sge_done:
        if (c_tx->pad) {
                *(u32 *)c_tx->trailer.pad = 0;
                if (do_crc)
-                       crypto_shash_update(c_tx->mpa_crc_hd,
-                               (u8 *)&c_tx->trailer.crc - c_tx->pad,
-                               c_tx->pad);
+                       siw_crc_update(&c_tx->mpa_crc,
+                                      (u8 *)&c_tx->trailer.crc - c_tx->pad,
+                                      c_tx->pad);
        }
-       if (!c_tx->mpa_crc_hd)
+       if (!c_tx->mpa_crc_enabled)
                c_tx->trailer.crc = 0;
        else if (do_crc)
-               crypto_shash_final(c_tx->mpa_crc_hd, (u8 *)&c_tx->trailer.crc);
+               siw_crc_final(&c_tx->mpa_crc, (u8 *)&c_tx->trailer.crc);
 
        data_len = c_tx->bytes_unsent;
 
@@ -736,10 +731,9 @@ static void siw_prepare_fpdu(struct siw_qp *qp, struct siw_wqe *wqe)
        /*
         * Init MPA CRC computation
         */
-       if (c_tx->mpa_crc_hd) {
-               crypto_shash_init(c_tx->mpa_crc_hd);
-               crypto_shash_update(c_tx->mpa_crc_hd, (u8 *)&c_tx->pkt,
-                                   c_tx->ctrl_len);
+       if (c_tx->mpa_crc_enabled) {
+               siw_crc_init(&c_tx->mpa_crc);
+               siw_crc_update(&c_tx->mpa_crc, &c_tx->pkt, c_tx->ctrl_len);
                c_tx->do_crc = 1;
        }
 }
index 5ac8bd450d240724d55de641fd0aef2f07a7b68d..fd7b266a221b2ccd95dc4abcf9561e9dda8155f5 100644 (file)
@@ -631,9 +631,6 @@ int siw_destroy_qp(struct ib_qp *base_qp, struct ib_udata *udata)
        }
        up_write(&qp->state_lock);
 
-       kfree(qp->tx_ctx.mpa_crc_hd);
-       kfree(qp->rx_stream.mpa_crc_hd);
-
        qp->scq = qp->rcq = NULL;
 
        siw_qp_put(qp);