Skip to content

Commit cee2688

Browse files
yonatancodledford
authored andcommitted
IB/rxe: Offload CRC calculation when possible
Use CPU ability to perform CRC calculations, by replacing direct calls to crc32_le() with crypto_shash_updata(). The overall performance gain measured with ib_send_bw tool is 10% and it was tested on "Intel CPU ES-2660 v2 @ 2.20Ghz" CPU. ib_send_bw -d rxe0 -x 1 -n 9000 -e -s $((1024 * 1024 )) -l 100 --------------------------------------------------------------------------------------------- | | bytes | iterations | BW peak[MB/sec] | BW average[MB/sec] | MsgRate[Mpps] | --------------------------------------------------------------------------------------------- | crc32_le | 1048576 | 9000 | inf | 497.60 | 0.000498 | | CRC offload | 1048576 | 9000 | inf | 546.70 | 0.000547 | --------------------------------------------------------------------------------------------- Fixes: 8700e3e ("Soft RoCE driver") Signed-off-by: Yonatan Cohen <yonatanc@mellanox.com> Signed-off-by: Leon Romanovsky <leon@kernel.org> Signed-off-by: Doug Ledford <dledford@redhat.com>
1 parent 0d38ac8 commit cee2688

File tree

9 files changed

+44
-9
lines changed

9 files changed

+44
-9
lines changed

drivers/infiniband/sw/rxe/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ config RDMA_RXE
22
tristate "Software RDMA over Ethernet (RoCE) driver"
33
depends on INET && PCI && INFINIBAND
44
depends on NET_UDP_TUNNEL
5+
depends on CRYPTO_CRC32
56
select DMA_VIRT_OPS
67
---help---
78
This driver implements the InfiniBand RDMA transport over

drivers/infiniband/sw/rxe/rxe.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ static void rxe_cleanup(struct rxe_dev *rxe)
6464
rxe_pool_cleanup(&rxe->mc_elem_pool);
6565

6666
rxe_cleanup_ports(rxe);
67+
68+
crypto_free_shash(rxe->tfm);
6769
}
6870

6971
/* called when all references have been dropped */

drivers/infiniband/sw/rxe/rxe.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
#include <rdma/ib_umem.h>
5151
#include <rdma/ib_cache.h>
5252
#include <rdma/ib_addr.h>
53+
#include <crypto/hash.h>
5354

5455
#include "rxe_net.h"
5556
#include "rxe_opcode.h"
@@ -64,6 +65,25 @@
6465

6566
#define RXE_ROCE_V2_SPORT (0xc000)
6667

68+
static inline u32 rxe_crc32(struct rxe_dev *rxe,
69+
u32 crc, void *next, size_t len)
70+
{
71+
int err;
72+
73+
SHASH_DESC_ON_STACK(shash, rxe->tfm);
74+
75+
shash->tfm = rxe->tfm;
76+
shash->flags = 0;
77+
*(u32 *)shash_desc_ctx(shash) = crc;
78+
err = crypto_shash_update(shash, next, len);
79+
if (unlikely(err)) {
80+
pr_warn_ratelimited("failed crc calculation, err: %d\n", err);
81+
return crc32_le(crc, next, len);
82+
}
83+
84+
return *(u32 *)shash_desc_ctx(shash);
85+
}
86+
6787
int rxe_set_mtu(struct rxe_dev *rxe, unsigned int dev_mtu);
6888

6989
int rxe_add(struct rxe_dev *rxe, unsigned int mtu);

drivers/infiniband/sw/rxe/rxe_icrc.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,10 +87,10 @@ u32 rxe_icrc_hdr(struct rxe_pkt_info *pkt, struct sk_buff *skb)
8787
bth->qpn |= cpu_to_be32(~BTH_QPN_MASK);
8888

8989
length = hdr_size + RXE_BTH_BYTES;
90-
crc = crc32_le(crc, pshdr, length);
90+
crc = rxe_crc32(pkt->rxe, crc, pshdr, length);
9191

9292
/* And finish to compute the CRC on the remainder of the headers. */
93-
crc = crc32_le(crc, pkt->hdr + RXE_BTH_BYTES,
94-
rxe_opcode[pkt->opcode].length - RXE_BTH_BYTES);
93+
crc = rxe_crc32(pkt->rxe, crc, pkt->hdr + RXE_BTH_BYTES,
94+
rxe_opcode[pkt->opcode].length - RXE_BTH_BYTES);
9595
return crc;
9696
}

drivers/infiniband/sw/rxe/rxe_mr.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,8 @@ int rxe_mem_copy(struct rxe_mem *mem, u64 iova, void *addr, int length,
370370
((void *)(uintptr_t)iova) : addr;
371371

372372
if (crcp)
373-
*crcp = crc32_le(*crcp, src, length);
373+
crc = rxe_crc32(to_rdev(mem->pd->ibpd.device),
374+
*crcp, src, length);
374375

375376
memcpy(dest, src, length);
376377

@@ -403,7 +404,8 @@ int rxe_mem_copy(struct rxe_mem *mem, u64 iova, void *addr, int length,
403404
bytes = length;
404405

405406
if (crcp)
406-
crc = crc32_le(crc, src, bytes);
407+
crc = rxe_crc32(to_rdev(mem->pd->ibpd.device),
408+
crc, src, bytes);
407409

408410
memcpy(dest, src, bytes);
409411

drivers/infiniband/sw/rxe/rxe_recv.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -387,8 +387,8 @@ int rxe_rcv(struct sk_buff *skb)
387387
pack_icrc = be32_to_cpu(*icrcp);
388388

389389
calc_icrc = rxe_icrc_hdr(pkt, skb);
390-
calc_icrc = crc32_le(calc_icrc, (u8 *)payload_addr(pkt),
391-
payload_size(pkt));
390+
calc_icrc = rxe_crc32(rxe, calc_icrc, (u8 *)payload_addr(pkt),
391+
payload_size(pkt));
392392
calc_icrc = (__force u32)cpu_to_be32(~calc_icrc);
393393
if (unlikely(calc_icrc != pack_icrc)) {
394394
if (skb->protocol == htons(ETH_P_IPV6))

drivers/infiniband/sw/rxe/rxe_req.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
*/
3333

3434
#include <linux/skbuff.h>
35+
#include <crypto/hash.h>
3536

3637
#include "rxe.h"
3738
#include "rxe_loc.h"
@@ -483,8 +484,7 @@ static int fill_packet(struct rxe_qp *qp, struct rxe_send_wqe *wqe,
483484
if (wqe->wr.send_flags & IB_SEND_INLINE) {
484485
u8 *tmp = &wqe->dma.inline_data[wqe->dma.sge_offset];
485486

486-
crc = crc32_le(crc, tmp, paylen);
487-
487+
crc = rxe_crc32(rxe, crc, tmp, paylen);
488488
memcpy(payload_addr(pkt), tmp, paylen);
489489

490490
wqe->dma.resid -= paylen;

drivers/infiniband/sw/rxe/rxe_verbs.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1322,6 +1322,13 @@ int rxe_register_device(struct rxe_dev *rxe)
13221322
dev->get_hw_stats = rxe_ib_get_hw_stats;
13231323
dev->alloc_hw_stats = rxe_ib_alloc_hw_stats;
13241324

1325+
rxe->tfm = crypto_alloc_shash("crc32", 0, 0);
1326+
if (IS_ERR(rxe->tfm)) {
1327+
pr_err("failed to allocate crc algorithmi err:%ld",
1328+
PTR_ERR(rxe->tfm));
1329+
return PTR_ERR(rxe->tfm);
1330+
}
1331+
13251332
err = ib_register_device(dev, NULL);
13261333
if (err) {
13271334
pr_warn("rxe_register_device failed, err = %d\n", err);
@@ -1342,6 +1349,8 @@ int rxe_register_device(struct rxe_dev *rxe)
13421349
err2:
13431350
ib_unregister_device(dev);
13441351
err1:
1352+
crypto_free_shash(rxe->tfm);
1353+
13451354
return err;
13461355
}
13471356

drivers/infiniband/sw/rxe/rxe_verbs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,7 @@ struct rxe_dev {
406406

407407
struct rxe_port port;
408408
struct list_head list;
409+
struct crypto_shash *tfm;
409410
};
410411

411412
static inline void rxe_counter_inc(struct rxe_dev *rxe, enum rxe_counters cnt)

0 commit comments

Comments
 (0)