Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5bb7d929 authored by Hoang-Nam Nguyen's avatar Hoang-Nam Nguyen Committed by Roland Dreier
Browse files

IB/ehca: Support large page MRs



Add support for MR pages larger than 4K on eHCA2. This reduces
firmware memory consumption.  If enabled via the mr_largepage module
parameter, the MR page size will be determined based on the MR length
and the hardware capabilities -- if the MR is >= 16M, 16M pages are
used, for example.

Signed-off-by: default avatarJoachim Fenkes <fenkes@de.ibm.com>
Signed-off-by: default avatarRoland Dreier <rolandd@cisco.com>
parent 23f1b384
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -100,6 +100,11 @@ struct ehca_sport {
	struct ehca_sma_attr saved_attr;
};

#define HCA_CAP_MR_PGSIZE_4K  1
#define HCA_CAP_MR_PGSIZE_64K 2
#define HCA_CAP_MR_PGSIZE_1M  4
#define HCA_CAP_MR_PGSIZE_16M 8

struct ehca_shca {
	struct ib_device ib_device;
	struct ibmebus_dev *ibmebus_dev;
@@ -115,6 +120,8 @@ struct ehca_shca {
	struct h_galpas galpas;
	struct mutex modify_mutex;
	u64 hca_cap;
	/* MR pgsize: bit 0-3 means 4K, 64K, 1M, 16M respectively */
	u32 hca_cap_mr_pgsize;
	int max_mtu;
};

@@ -206,6 +213,7 @@ struct ehca_mr {
	enum ehca_mr_flag flags;
	u32 num_kpages;		/* number of kernel pages */
	u32 num_hwpages;	/* number of hw pages to form MR */
	u64 hwpage_size;	/* hw page size used for this MR */
	int acl;		/* ACL (stored here for usage in reregister) */
	u64 *start;		/* virtual start address (stored here for */
				/* usage in reregister) */
@@ -240,6 +248,7 @@ struct ehca_mr_pginfo {
	enum ehca_mr_pgi_type type;
	u64 num_kpages;
	u64 kpage_cnt;
	u64 hwpage_size;     /* hw page size used for this MR */
	u64 num_hwpages;     /* number of hw pages */
	u64 hwpage_cnt;      /* counter for hw pages */
	u64 next_hwpage;     /* next hw page in buffer/chunk/listelem */
+17 −1
Original line number Diff line number Diff line
@@ -63,6 +63,7 @@ int ehca_port_act_time = 30;
int ehca_poll_all_eqs  = 1;
int ehca_static_rate   = -1;
int ehca_scaling_code  = 0;
int ehca_mr_largepage  = 0;

module_param_named(open_aqp1,     ehca_open_aqp1,     int, 0);
module_param_named(debug_level,   ehca_debug_level,   int, 0);
@@ -73,6 +74,7 @@ module_param_named(port_act_time, ehca_port_act_time, int, 0);
module_param_named(poll_all_eqs,  ehca_poll_all_eqs,  int, 0);
module_param_named(static_rate,   ehca_static_rate,   int, 0);
module_param_named(scaling_code,  ehca_scaling_code,  int, 0);
module_param_named(mr_largepage,  ehca_mr_largepage,  int, 0);

MODULE_PARM_DESC(open_aqp1,
		 "AQP1 on startup (0: no (default), 1: yes)");
@@ -95,6 +97,9 @@ MODULE_PARM_DESC(static_rate,
		 "set permanent static rate (default: disabled)");
MODULE_PARM_DESC(scaling_code,
		 "set scaling code (0: disabled/default, 1: enabled)");
MODULE_PARM_DESC(mr_largepage,
		 "use large page for MR (0: use PAGE_SIZE (default), "
		 "1: use large page depending on MR size");

DEFINE_RWLOCK(ehca_qp_idr_lock);
DEFINE_RWLOCK(ehca_cq_idr_lock);
@@ -295,6 +300,8 @@ int ehca_sense_attributes(struct ehca_shca *shca)
		if (EHCA_BMASK_GET(hca_cap_descr[i].mask, shca->hca_cap))
			ehca_gen_dbg("   %s", hca_cap_descr[i].descr);

	shca->hca_cap_mr_pgsize = rblock->memory_page_size_supported;

	port = (struct hipz_query_port *)rblock;
	h_ret = hipz_h_query_port(shca->ipz_hca_handle, 1, port);
	if (h_ret != H_SUCCESS) {
@@ -590,6 +597,14 @@ static ssize_t ehca_show_adapter_handle(struct device *dev,
}
static DEVICE_ATTR(adapter_handle, S_IRUGO, ehca_show_adapter_handle, NULL);

static ssize_t ehca_show_mr_largepage(struct device *dev,
				      struct device_attribute *attr,
				      char *buf)
{
	return sprintf(buf, "%d\n", ehca_mr_largepage);
}
static DEVICE_ATTR(mr_largepage, S_IRUGO, ehca_show_mr_largepage, NULL);

static struct attribute *ehca_dev_attrs[] = {
	&dev_attr_adapter_handle.attr,
	&dev_attr_num_ports.attr,
@@ -606,6 +621,7 @@ static struct attribute *ehca_dev_attrs[] = {
	&dev_attr_cur_mw.attr,
	&dev_attr_max_pd.attr,
	&dev_attr_max_ah.attr,
	&dev_attr_mr_largepage.attr,
	NULL
};

+311 −60

File changed.

Preview size limit exceeded, changes collapsed.

+1 −1
Original line number Diff line number Diff line
@@ -111,7 +111,7 @@ int ehca_mr_is_maxmr(u64 size,
void ehca_mrmw_map_acl(int ib_acl,
		       u32 *hipz_acl);

void ehca_mrmw_set_pgsize_hipz_acl(u32 *hipz_acl);
void ehca_mrmw_set_pgsize_hipz_acl(u32 pgsize, u32 *hipz_acl);

void ehca_mrmw_reverse_map_acl(const u32 *hipz_acl,
			       int *ib_acl);
+19 −1
Original line number Diff line number Diff line
@@ -427,7 +427,8 @@ u64 hipz_h_register_rpage(const struct ipz_adapter_handle adapter_handle,
{
	return ehca_plpar_hcall_norets(H_REGISTER_RPAGES,
				       adapter_handle.handle,      /* r4  */
				       queue_type | pagesize << 8, /* r5  */
				       (u64)queue_type | ((u64)pagesize) << 8,
				       /* r5  */
				       resource_handle,	           /* r6  */
				       logical_address_of_page,    /* r7  */
				       count,	                   /* r8  */
@@ -724,6 +725,9 @@ u64 hipz_h_alloc_resource_mr(const struct ipz_adapter_handle adapter_handle,
	u64 ret;
	u64 outs[PLPAR_HCALL9_BUFSIZE];

	ehca_gen_dbg("kernel PAGE_SIZE=%x access_ctrl=%016x "
		     "vaddr=%lx length=%lx",
		     (u32)PAGE_SIZE, access_ctrl, vaddr, length);
	ret = ehca_plpar_hcall9(H_ALLOC_RESOURCE, outs,
				adapter_handle.handle,            /* r4 */
				5,                                /* r5 */
@@ -746,8 +750,22 @@ u64 hipz_h_register_rpage_mr(const struct ipz_adapter_handle adapter_handle,
			     const u64 logical_address_of_page,
			     const u64 count)
{
	extern int ehca_debug_level;
	u64 ret;

	if (unlikely(ehca_debug_level >= 2)) {
		if (count > 1) {
			u64 *kpage;
			int i;
			kpage = (u64 *)abs_to_virt(logical_address_of_page);
			for (i = 0; i < count; i++)
				ehca_gen_dbg("kpage[%d]=%p",
					     i, (void *)kpage[i]);
		} else
			ehca_gen_dbg("kpage=%p",
				     (void *)logical_address_of_page);
	}

	if ((count > 1) && (logical_address_of_page & (EHCA_PAGESIZE-1))) {
		ehca_gen_err("logical_address_of_page not on a 4k boundary "
			     "adapter_handle=%lx mr=%p mr_handle=%lx "