Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
drivers
net
ethernet
mellanox
mlx4
profile.c
Go to the documentation of this file.
1
/*
2
* Copyright (c) 2004, 2005 Topspin Communications. All rights reserved.
3
* Copyright (c) 2005 Mellanox Technologies. All rights reserved.
4
* Copyright (c) 2006, 2007 Cisco Systems, Inc. All rights reserved.
5
*
6
* This software is available to you under a choice of one of two
7
* licenses. You may choose to be licensed under the terms of the GNU
8
* General Public License (GPL) Version 2, available from the file
9
* COPYING in the main directory of this source tree, or the
10
* OpenIB.org BSD license below:
11
*
12
* Redistribution and use in source and binary forms, with or
13
* without modification, are permitted provided that the following
14
* conditions are met:
15
*
16
* - Redistributions of source code must retain the above
17
* copyright notice, this list of conditions and the following
18
* disclaimer.
19
*
20
* - Redistributions in binary form must reproduce the above
21
* copyright notice, this list of conditions and the following
22
* disclaimer in the documentation and/or other materials
23
* provided with the distribution.
24
*
25
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
29
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
30
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
31
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
32
* SOFTWARE.
33
*/
34
35
#include <linux/slab.h>
36
37
#include "
mlx4.h
"
38
#include "
fw.h
"
39
40
enum
{
41
MLX4_RES_QP
,
42
MLX4_RES_RDMARC
,
43
MLX4_RES_ALTC
,
44
MLX4_RES_AUXC
,
45
MLX4_RES_SRQ
,
46
MLX4_RES_CQ
,
47
MLX4_RES_EQ
,
48
MLX4_RES_DMPT
,
49
MLX4_RES_CMPT
,
50
MLX4_RES_MTT
,
51
MLX4_RES_MCG
,
52
MLX4_RES_NUM
53
};
54
55
static
const
char
*res_name[] = {
56
[
MLX4_RES_QP
] =
"QP"
,
57
[
MLX4_RES_RDMARC
] =
"RDMARC"
,
58
[
MLX4_RES_ALTC
] =
"ALTC"
,
59
[
MLX4_RES_AUXC
] =
"AUXC"
,
60
[
MLX4_RES_SRQ
] =
"SRQ"
,
61
[
MLX4_RES_CQ
] =
"CQ"
,
62
[
MLX4_RES_EQ
] =
"EQ"
,
63
[
MLX4_RES_DMPT
] =
"DMPT"
,
64
[
MLX4_RES_CMPT
] =
"CMPT"
,
65
[
MLX4_RES_MTT
] =
"MTT"
,
66
[
MLX4_RES_MCG
] =
"MCG"
,
67
};
68
69
u64
mlx4_make_profile
(
struct
mlx4_dev
*
dev
,
70
struct
mlx4_profile
*
request
,
71
struct
mlx4_dev_cap
*dev_cap,
72
struct
mlx4_init_hca_param
*init_hca)
73
{
74
struct
mlx4_priv
*
priv
=
mlx4_priv
(dev);
75
struct
mlx4_resource
{
76
u64
size
;
77
u64
start
;
78
int
type
;
79
u32
num
;
80
int
log_num;
81
};
82
83
u64
total_size
= 0;
84
struct
mlx4_resource
*
profile
;
85
struct
mlx4_resource
tmp;
86
struct
sysinfo
si;
87
int
i
,
j
;
88
89
profile = kcalloc(
MLX4_RES_NUM
,
sizeof
(*profile),
GFP_KERNEL
);
90
if
(!profile)
91
return
-
ENOMEM
;
92
93
/*
94
* We want to scale the number of MTTs with the size of the
95
* system memory, since it makes sense to register a lot of
96
* memory on a system with a lot of memory. As a heuristic,
97
* make sure we have enough MTTs to cover twice the system
98
* memory (with PAGE_SIZE entries).
99
*
100
* This number has to be a power of two and fit into 32 bits
101
* due to device limitations, so cap this at 2^31 as well.
102
* That limits us to 8TB of memory registration per HCA with
103
* 4KB pages, which is probably OK for the next few months.
104
*/
105
si_meminfo
(&si);
106
request->
num_mtt
=
107
roundup_pow_of_two
(
max_t
(
unsigned
, request->
num_mtt
,
108
min
(1
UL
<< (31 -
log_mtts_per_seg
),
109
si.
totalram
>> (
log_mtts_per_seg
- 1))));
110
111
profile[
MLX4_RES_QP
].size = dev_cap->
qpc_entry_sz
;
112
profile[
MLX4_RES_RDMARC
].size = dev_cap->
rdmarc_entry_sz
;
113
profile[
MLX4_RES_ALTC
].size = dev_cap->
altc_entry_sz
;
114
profile[
MLX4_RES_AUXC
].size = dev_cap->
aux_entry_sz
;
115
profile[
MLX4_RES_SRQ
].size = dev_cap->
srq_entry_sz
;
116
profile[
MLX4_RES_CQ
].size = dev_cap->
cqc_entry_sz
;
117
profile[
MLX4_RES_EQ
].size = dev_cap->
eqc_entry_sz
;
118
profile[
MLX4_RES_DMPT
].size = dev_cap->
dmpt_entry_sz
;
119
profile[
MLX4_RES_CMPT
].size = dev_cap->
cmpt_entry_sz
;
120
profile[
MLX4_RES_MTT
].size = dev_cap->
mtt_entry_sz
;
121
profile[
MLX4_RES_MCG
].size =
mlx4_get_mgm_entry_size
(dev);
122
123
profile[
MLX4_RES_QP
].num = request->
num_qp
;
124
profile[
MLX4_RES_RDMARC
].num = request->
num_qp
* request->
rdmarc_per_qp
;
125
profile[
MLX4_RES_ALTC
].num = request->
num_qp
;
126
profile[
MLX4_RES_AUXC
].num = request->
num_qp
;
127
profile[
MLX4_RES_SRQ
].num = request->
num_srq
;
128
profile[
MLX4_RES_CQ
].num = request->
num_cq
;
129
profile[
MLX4_RES_EQ
].num = mlx4_is_mfunc(dev) ?
130
dev->
phys_caps
.num_phys_eqs :
131
min_t
(
unsigned
, dev_cap->
max_eqs
,
MAX_MSIX
);
132
profile[
MLX4_RES_DMPT
].num = request->
num_mpt
;
133
profile[
MLX4_RES_CMPT
].num =
MLX4_NUM_CMPTS
;
134
profile[
MLX4_RES_MTT
].num = request->
num_mtt
* (1 <<
log_mtts_per_seg
);
135
profile[
MLX4_RES_MCG
].num = request->
num_mcg
;
136
137
for
(i = 0; i <
MLX4_RES_NUM
; ++
i
) {
138
profile[
i
].type =
i
;
139
profile[
i
].num =
roundup_pow_of_two
(profile[i].
num
);
140
profile[
i
].log_num =
ilog2
(profile[i].num);
141
profile[
i
].size *= profile[
i
].num;
142
profile[
i
].size =
max
(profile[i].
size
, (
u64
)
PAGE_SIZE
);
143
}
144
145
/*
146
* Sort the resources in decreasing order of size. Since they
147
* all have sizes that are powers of 2, we'll be able to keep
148
* resources aligned to their size and pack them without gaps
149
* using the sorted order.
150
*/
151
for
(i = MLX4_RES_NUM; i > 0; --
i
)
152
for
(j = 1; j <
i
; ++
j
) {
153
if
(profile[j].
size
> profile[j - 1].
size
) {
154
tmp = profile[
j
];
155
profile[
j
] = profile[j - 1];
156
profile[j - 1] =
tmp
;
157
}
158
}
159
160
for
(i = 0; i <
MLX4_RES_NUM
; ++
i
) {
161
if
(profile[i].
size
) {
162
profile[
i
].start =
total_size
;
163
total_size += profile[
i
].size;
164
}
165
166
if
(total_size > dev_cap->
max_icm_sz
) {
167
mlx4_err
(dev,
"Profile requires 0x%llx bytes; "
168
"won't fit in 0x%llx bytes of context memory.\n"
,
169
(
unsigned
long
long
) total_size,
170
(
unsigned
long
long
) dev_cap->
max_icm_sz
);
171
kfree
(profile);
172
return
-
ENOMEM
;
173
}
174
175
if
(profile[i].size)
176
mlx4_dbg
(dev,
" profile[%2d] (%6s): 2^%02d entries @ 0x%10llx, "
177
"size 0x%10llx\n"
,
178
i, res_name[profile[i].
type
], profile[i].log_num,
179
(
unsigned
long
long
) profile[i].
start
,
180
(
unsigned
long
long
) profile[i].size);
181
}
182
183
mlx4_dbg
(dev,
"HCA context memory: reserving %d KB\n"
,
184
(
int
) (total_size >> 10));
185
186
for
(i = 0; i <
MLX4_RES_NUM
; ++
i
) {
187
switch
(profile[i].
type
) {
188
case
MLX4_RES_QP
:
189
dev->
caps
.num_qps = profile[
i
].num;
190
init_hca->
qpc_base
= profile[
i
].start;
191
init_hca->
log_num_qps
= profile[
i
].log_num;
192
break
;
193
case
MLX4_RES_RDMARC
:
194
for
(priv->
qp_table
.rdmarc_shift = 0;
195
request->
num_qp
<< priv->
qp_table
.rdmarc_shift < profile[i].num;
196
++priv->
qp_table
.rdmarc_shift)
197
;
/* nothing */
198
dev->
caps
.max_qp_dest_rdma = 1 << priv->
qp_table
.rdmarc_shift;
199
priv->
qp_table
.rdmarc_base = (
u32
) profile[i].
start
;
200
init_hca->
rdmarc_base
= profile[
i
].start;
201
init_hca->
log_rd_per_qp
= priv->
qp_table
.rdmarc_shift;
202
break
;
203
case
MLX4_RES_ALTC
:
204
init_hca->
altc_base
= profile[
i
].start;
205
break
;
206
case
MLX4_RES_AUXC
:
207
init_hca->
auxc_base
= profile[
i
].start;
208
break
;
209
case
MLX4_RES_SRQ
:
210
dev->
caps
.num_srqs = profile[
i
].num;
211
init_hca->
srqc_base
= profile[
i
].start;
212
init_hca->
log_num_srqs
= profile[
i
].log_num;
213
break
;
214
case
MLX4_RES_CQ
:
215
dev->
caps
.num_cqs = profile[
i
].num;
216
init_hca->
cqc_base
= profile[
i
].start;
217
init_hca->
log_num_cqs
= profile[
i
].log_num;
218
break
;
219
case
MLX4_RES_EQ
:
220
dev->
caps
.num_eqs =
roundup_pow_of_two
(
min_t
(
unsigned
, dev_cap->
max_eqs
,
221
MAX_MSIX
));
222
init_hca->
eqc_base
= profile[
i
].start;
223
init_hca->
log_num_eqs
=
ilog2
(dev->
caps
.num_eqs);
224
break
;
225
case
MLX4_RES_DMPT
:
226
dev->
caps
.num_mpts = profile[
i
].num;
227
priv->
mr_table
.mpt_base = profile[
i
].start;
228
init_hca->
dmpt_base
= profile[
i
].start;
229
init_hca->
log_mpt_sz
= profile[
i
].log_num;
230
break
;
231
case
MLX4_RES_CMPT
:
232
init_hca->
cmpt_base
= profile[
i
].start;
233
break
;
234
case
MLX4_RES_MTT
:
235
dev->
caps
.num_mtts = profile[
i
].num;
236
priv->
mr_table
.mtt_base = profile[
i
].start;
237
init_hca->
mtt_base
= profile[
i
].start;
238
break
;
239
case
MLX4_RES_MCG
:
240
init_hca->
mc_base
= profile[
i
].start;
241
init_hca->
log_mc_entry_sz
=
242
ilog2
(
mlx4_get_mgm_entry_size
(dev));
243
init_hca->
log_mc_table_sz
= profile[
i
].log_num;
244
if
(dev->
caps
.steering_mode ==
245
MLX4_STEERING_MODE_DEVICE_MANAGED
) {
246
dev->
caps
.num_mgms = profile[
i
].num;
247
}
else
{
248
init_hca->
log_mc_hash_sz
=
249
profile[
i
].log_num - 1;
250
dev->
caps
.num_mgms = profile[
i
].num >> 1;
251
dev->
caps
.num_amgms = profile[
i
].num >> 1;
252
}
253
break
;
254
default
:
255
break
;
256
}
257
}
258
259
/*
260
* PDs don't take any HCA memory, but we assign them as part
261
* of the HCA profile anyway.
262
*/
263
dev->
caps
.num_pds =
MLX4_NUM_PDS
;
264
265
kfree
(profile);
266
return
total_size
;
267
}
Generated on Thu Jan 10 2013 13:05:33 for Linux Kernel by
1.8.2