mirror of
https://github.com/torvalds/linux.git
synced 2024-11-22 12:11:40 +00:00
e9a53e73a2
Replace the old signature handover API with the new one. The new API simplifes PI handover code complexity for ULPs and improve performance. For RW API it will reduce the maximum number of work requests per task and the need of dealing with multiple MRs (and their registrations and invalidations) per task. All the mappings and registration of the data and the protection buffers is done by the LLD using a single WR and a special MR type (IB_MR_TYPE_INTEGRITY) for the PI handover operation. The setup of the tested benchmark (using iSER ULP): - 2 servers with 24 cores (1 initiator and 1 target) - ConnectX-4/ConnectX-5 adapters - 24 target sessions with 1 LUN each - ramdisk backstore - PI active Performance results running fio (24 jobs, 128 iodepth) using write_generate=1 and read_verify=1 (w/w.o patch): bs IOPS(read) IOPS(write) ---- ---------- ---------- 512 1243.3K/1182.3K 1725.1K/1680.2K 4k 571233/528835 743293/748259 32k 72388/71086 71789/93573 Using write_generate=0 and read_verify=0 (w/w.o patch): bs IOPS(read) IOPS(write) ---- ---------- ---------- 512 1572.1K/1427.2K 1823.5K/1724.3K 4k 921992/916194 753772/768267 32k 75052/73960 73180/95484 There is a performance degradation when writing big block sizes. Degradation is caused by the complexity of combining multiple indirections and perform RDMA READ operation from it. This will be fixed in the following patches by reducing the indirections if possible. Signed-off-by: Israel Rukshin <israelr@mellanox.com> Reviewed-by: Max Gurtovoy <maxg@mellanox.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
82 lines
2.6 KiB
C
82 lines
2.6 KiB
C
/*
|
|
* Copyright (c) 2016 HGST, a Western Digital Company.
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
* under the terms and conditions of the GNU General Public License,
|
|
* version 2, as published by the Free Software Foundation.
|
|
*
|
|
* This program is distributed in the hope it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
* more details.
|
|
*/
|
|
#ifndef _RDMA_RW_H
|
|
#define _RDMA_RW_H
|
|
|
|
#include <linux/dma-mapping.h>
|
|
#include <linux/scatterlist.h>
|
|
#include <rdma/ib_verbs.h>
|
|
#include <rdma/rdma_cm.h>
|
|
#include <rdma/mr_pool.h>
|
|
|
|
struct rdma_rw_ctx {
|
|
/* number of RDMA READ/WRITE WRs (not counting MR WRs) */
|
|
u32 nr_ops;
|
|
|
|
/* tag for the union below: */
|
|
u8 type;
|
|
|
|
union {
|
|
/* for mapping a single SGE: */
|
|
struct {
|
|
struct ib_sge sge;
|
|
struct ib_rdma_wr wr;
|
|
} single;
|
|
|
|
/* for mapping of multiple SGEs: */
|
|
struct {
|
|
struct ib_sge *sges;
|
|
struct ib_rdma_wr *wrs;
|
|
} map;
|
|
|
|
/* for registering multiple WRs: */
|
|
struct rdma_rw_reg_ctx {
|
|
struct ib_sge sge;
|
|
struct ib_rdma_wr wr;
|
|
struct ib_reg_wr reg_wr;
|
|
struct ib_send_wr inv_wr;
|
|
struct ib_mr *mr;
|
|
} *reg;
|
|
};
|
|
};
|
|
|
|
int rdma_rw_ctx_init(struct rdma_rw_ctx *ctx, struct ib_qp *qp, u8 port_num,
|
|
struct scatterlist *sg, u32 sg_cnt, u32 sg_offset,
|
|
u64 remote_addr, u32 rkey, enum dma_data_direction dir);
|
|
void rdma_rw_ctx_destroy(struct rdma_rw_ctx *ctx, struct ib_qp *qp, u8 port_num,
|
|
struct scatterlist *sg, u32 sg_cnt,
|
|
enum dma_data_direction dir);
|
|
|
|
int rdma_rw_ctx_signature_init(struct rdma_rw_ctx *ctx, struct ib_qp *qp,
|
|
u8 port_num, struct scatterlist *sg, u32 sg_cnt,
|
|
struct scatterlist *prot_sg, u32 prot_sg_cnt,
|
|
struct ib_sig_attrs *sig_attrs, u64 remote_addr, u32 rkey,
|
|
enum dma_data_direction dir);
|
|
void rdma_rw_ctx_destroy_signature(struct rdma_rw_ctx *ctx, struct ib_qp *qp,
|
|
u8 port_num, struct scatterlist *sg, u32 sg_cnt,
|
|
struct scatterlist *prot_sg, u32 prot_sg_cnt,
|
|
enum dma_data_direction dir);
|
|
|
|
struct ib_send_wr *rdma_rw_ctx_wrs(struct rdma_rw_ctx *ctx, struct ib_qp *qp,
|
|
u8 port_num, struct ib_cqe *cqe, struct ib_send_wr *chain_wr);
|
|
int rdma_rw_ctx_post(struct rdma_rw_ctx *ctx, struct ib_qp *qp, u8 port_num,
|
|
struct ib_cqe *cqe, struct ib_send_wr *chain_wr);
|
|
|
|
unsigned int rdma_rw_mr_factor(struct ib_device *device, u8 port_num,
|
|
unsigned int maxpages);
|
|
void rdma_rw_init_qp(struct ib_device *dev, struct ib_qp_init_attr *attr);
|
|
int rdma_rw_init_mrs(struct ib_qp *qp, struct ib_qp_init_attr *attr);
|
|
void rdma_rw_cleanup_mrs(struct ib_qp *qp);
|
|
|
|
#endif /* _RDMA_RW_H */
|