@@ -992,6 +992,80 @@ static int mlx5_ib_modify_port(struct ib_device *ibdev, u8 port, int mask,
992
992
return err ;
993
993
}
994
994
995
+ static int calc_total_bfregs (struct mlx5_ib_dev * dev , bool lib_uar_4k ,
996
+ struct mlx5_ib_alloc_ucontext_req_v2 * req ,
997
+ u32 * num_sys_pages )
998
+ {
999
+ int uars_per_sys_page ;
1000
+ int bfregs_per_sys_page ;
1001
+ int ref_bfregs = req -> total_num_bfregs ;
1002
+
1003
+ if (req -> total_num_bfregs == 0 )
1004
+ return - EINVAL ;
1005
+
1006
+ BUILD_BUG_ON (MLX5_MAX_BFREGS % MLX5_NON_FP_BFREGS_IN_PAGE );
1007
+ BUILD_BUG_ON (MLX5_MAX_BFREGS < MLX5_NON_FP_BFREGS_IN_PAGE );
1008
+
1009
+ if (req -> total_num_bfregs > MLX5_MAX_BFREGS )
1010
+ return - ENOMEM ;
1011
+
1012
+ uars_per_sys_page = get_uars_per_sys_page (dev , lib_uar_4k );
1013
+ bfregs_per_sys_page = uars_per_sys_page * MLX5_NON_FP_BFREGS_PER_UAR ;
1014
+ req -> total_num_bfregs = ALIGN (req -> total_num_bfregs , bfregs_per_sys_page );
1015
+ * num_sys_pages = req -> total_num_bfregs / bfregs_per_sys_page ;
1016
+
1017
+ if (req -> num_low_latency_bfregs > req -> total_num_bfregs - 1 )
1018
+ return - EINVAL ;
1019
+
1020
+ mlx5_ib_dbg (dev , "uar_4k: fw support %s, lib support %s, user requested %d bfregs, alloated %d, using %d sys pages\n" ,
1021
+ MLX5_CAP_GEN (dev -> mdev , uar_4k ) ? "yes" : "no" ,
1022
+ lib_uar_4k ? "yes" : "no" , ref_bfregs ,
1023
+ req -> total_num_bfregs , * num_sys_pages );
1024
+
1025
+ return 0 ;
1026
+ }
1027
+
1028
+ static int allocate_uars (struct mlx5_ib_dev * dev , struct mlx5_ib_ucontext * context )
1029
+ {
1030
+ struct mlx5_bfreg_info * bfregi ;
1031
+ int err ;
1032
+ int i ;
1033
+
1034
+ bfregi = & context -> bfregi ;
1035
+ for (i = 0 ; i < bfregi -> num_sys_pages ; i ++ ) {
1036
+ err = mlx5_cmd_alloc_uar (dev -> mdev , & bfregi -> sys_pages [i ]);
1037
+ if (err )
1038
+ goto error ;
1039
+
1040
+ mlx5_ib_dbg (dev , "allocated uar %d\n" , bfregi -> sys_pages [i ]);
1041
+ }
1042
+ return 0 ;
1043
+
1044
+ error :
1045
+ for (-- i ; i >= 0 ; i -- )
1046
+ if (mlx5_cmd_free_uar (dev -> mdev , bfregi -> sys_pages [i ]))
1047
+ mlx5_ib_warn (dev , "failed to free uar %d\n" , i );
1048
+
1049
+ return err ;
1050
+ }
1051
+
1052
+ static int deallocate_uars (struct mlx5_ib_dev * dev , struct mlx5_ib_ucontext * context )
1053
+ {
1054
+ struct mlx5_bfreg_info * bfregi ;
1055
+ int err ;
1056
+ int i ;
1057
+
1058
+ bfregi = & context -> bfregi ;
1059
+ for (i = 0 ; i < bfregi -> num_sys_pages ; i ++ ) {
1060
+ err = mlx5_cmd_free_uar (dev -> mdev , bfregi -> sys_pages [i ]);
1061
+ if (err ) {
1062
+ mlx5_ib_warn (dev , "failed to free uar %d\n" , i );
1063
+ return err ;
1064
+ }
1065
+ }
1066
+ return 0 ;
1067
+ }
1068
+
995
1069
static struct ib_ucontext * mlx5_ib_alloc_ucontext (struct ib_device * ibdev ,
996
1070
struct ib_udata * udata )
997
1071
{
@@ -1000,16 +1074,12 @@ static struct ib_ucontext *mlx5_ib_alloc_ucontext(struct ib_device *ibdev,
1000
1074
struct mlx5_ib_alloc_ucontext_resp resp = {};
1001
1075
struct mlx5_ib_ucontext * context ;
1002
1076
struct mlx5_bfreg_info * bfregi ;
1003
- struct mlx5_uar * uars ;
1004
- int gross_bfregs ;
1005
- int num_uars ;
1006
1077
int ver ;
1007
- int bfregn ;
1008
1078
int err ;
1009
- int i ;
1010
1079
size_t reqlen ;
1011
1080
size_t min_req_v2 = offsetof(struct mlx5_ib_alloc_ucontext_req_v2 ,
1012
1081
max_cqe_version );
1082
+ bool lib_uar_4k ;
1013
1083
1014
1084
if (!dev -> ib_active )
1015
1085
return ERR_PTR (- EAGAIN );
@@ -1032,27 +1102,14 @@ static struct ib_ucontext *mlx5_ib_alloc_ucontext(struct ib_device *ibdev,
1032
1102
if (req .flags )
1033
1103
return ERR_PTR (- EINVAL );
1034
1104
1035
- if (req .total_num_bfregs > MLX5_MAX_BFREGS )
1036
- return ERR_PTR (- ENOMEM );
1037
-
1038
- if (req .total_num_bfregs == 0 )
1039
- return ERR_PTR (- EINVAL );
1040
-
1041
1105
if (req .comp_mask || req .reserved0 || req .reserved1 || req .reserved2 )
1042
1106
return ERR_PTR (- EOPNOTSUPP );
1043
1107
1044
- if (reqlen > sizeof (req ) &&
1045
- !ib_is_udata_cleared (udata , sizeof (req ),
1046
- reqlen - sizeof (req )))
1047
- return ERR_PTR (- EOPNOTSUPP );
1048
-
1049
1108
req .total_num_bfregs = ALIGN (req .total_num_bfregs ,
1050
1109
MLX5_NON_FP_BFREGS_PER_UAR );
1051
1110
if (req .num_low_latency_bfregs > req .total_num_bfregs - 1 )
1052
1111
return ERR_PTR (- EINVAL );
1053
1112
1054
- num_uars = req .total_num_bfregs / MLX5_NON_FP_BFREGS_PER_UAR ;
1055
- gross_bfregs = num_uars * MLX5_BFREGS_PER_UAR ;
1056
1113
resp .qp_tab_size = 1 << MLX5_CAP_GEN (dev -> mdev , log_max_qp );
1057
1114
if (mlx5_core_is_pf (dev -> mdev ) && MLX5_CAP_GEN (dev -> mdev , bf ))
1058
1115
resp .bf_reg_size = 1 << MLX5_CAP_GEN (dev -> mdev , log_bf_reg_size );
@@ -1072,42 +1129,34 @@ static struct ib_ucontext *mlx5_ib_alloc_ucontext(struct ib_device *ibdev,
1072
1129
if (!context )
1073
1130
return ERR_PTR (- ENOMEM );
1074
1131
1132
+ lib_uar_4k = false;
1075
1133
bfregi = & context -> bfregi ;
1076
- mutex_init ( & bfregi -> lock );
1077
- uars = kcalloc ( num_uars , sizeof ( * uars ), GFP_KERNEL );
1078
- if (! uars ) {
1079
- err = - ENOMEM ;
1134
+
1135
+ /* updates req->total_num_bfregs */
1136
+ err = calc_total_bfregs ( dev , lib_uar_4k , & req , & bfregi -> num_sys_pages );
1137
+ if ( err )
1080
1138
goto out_ctx ;
1081
- }
1082
1139
1083
- bfregi -> bitmap = kcalloc (BITS_TO_LONGS (gross_bfregs ),
1084
- sizeof (* bfregi -> bitmap ),
1140
+ mutex_init (& bfregi -> lock );
1141
+ bfregi -> lib_uar_4k = lib_uar_4k ;
1142
+ bfregi -> count = kcalloc (req .total_num_bfregs , sizeof (* bfregi -> count ),
1085
1143
GFP_KERNEL );
1086
- if (!bfregi -> bitmap ) {
1144
+ if (!bfregi -> count ) {
1087
1145
err = - ENOMEM ;
1088
- goto out_uar_ctx ;
1089
- }
1090
- /*
1091
- * clear all fast path bfregs
1092
- */
1093
- for (i = 0 ; i < gross_bfregs ; i ++ ) {
1094
- bfregn = i & 3 ;
1095
- if (bfregn == 2 || bfregn == 3 )
1096
- set_bit (i , bfregi -> bitmap );
1146
+ goto out_ctx ;
1097
1147
}
1098
1148
1099
- bfregi -> count = kcalloc (gross_bfregs ,
1100
- sizeof (* bfregi -> count ), GFP_KERNEL );
1101
- if (!bfregi -> count ) {
1149
+ bfregi -> sys_pages = kcalloc (bfregi -> num_sys_pages ,
1150
+ sizeof (* bfregi -> sys_pages ),
1151
+ GFP_KERNEL );
1152
+ if (!bfregi -> sys_pages ) {
1102
1153
err = - ENOMEM ;
1103
- goto out_bitmap ;
1154
+ goto out_count ;
1104
1155
}
1105
1156
1106
- for (i = 0 ; i < num_uars ; i ++ ) {
1107
- err = mlx5_cmd_alloc_uar (dev -> mdev , & uars [i ].index );
1108
- if (err )
1109
- goto out_count ;
1110
- }
1157
+ err = allocate_uars (dev , context );
1158
+ if (err )
1159
+ goto out_sys_pages ;
1111
1160
1112
1161
#ifdef CONFIG_INFINIBAND_ON_DEMAND_PAGING
1113
1162
context -> ibucontext .invalidate_range = & mlx5_ib_invalidate_range ;
@@ -1166,9 +1215,8 @@ static struct ib_ucontext *mlx5_ib_alloc_ucontext(struct ib_device *ibdev,
1166
1215
1167
1216
bfregi -> ver = ver ;
1168
1217
bfregi -> num_low_latency_bfregs = req .num_low_latency_bfregs ;
1169
- bfregi -> uars = uars ;
1170
- bfregi -> num_uars = num_uars ;
1171
1218
context -> cqe_version = resp .cqe_version ;
1219
+ context -> lib_caps = false;
1172
1220
1173
1221
return & context -> ibucontext ;
1174
1222
@@ -1180,51 +1228,49 @@ static struct ib_ucontext *mlx5_ib_alloc_ucontext(struct ib_device *ibdev,
1180
1228
free_page (context -> upd_xlt_page );
1181
1229
1182
1230
out_uars :
1183
- for (i -- ; i >= 0 ; i -- )
1184
- mlx5_cmd_free_uar (dev -> mdev , uars [i ].index );
1185
- out_count :
1186
- kfree (bfregi -> count );
1231
+ deallocate_uars (dev , context );
1187
1232
1188
- out_bitmap :
1189
- kfree (bfregi -> bitmap );
1233
+ out_sys_pages :
1234
+ kfree (bfregi -> sys_pages );
1190
1235
1191
- out_uar_ctx :
1192
- kfree (uars );
1236
+ out_count :
1237
+ kfree (bfregi -> count );
1193
1238
1194
1239
out_ctx :
1195
1240
kfree (context );
1241
+
1196
1242
return ERR_PTR (err );
1197
1243
}
1198
1244
1199
1245
static int mlx5_ib_dealloc_ucontext (struct ib_ucontext * ibcontext )
1200
1246
{
1201
1247
struct mlx5_ib_ucontext * context = to_mucontext (ibcontext );
1202
1248
struct mlx5_ib_dev * dev = to_mdev (ibcontext -> device );
1203
- struct mlx5_bfreg_info * bfregi = & context -> bfregi ;
1204
- int i ;
1249
+ struct mlx5_bfreg_info * bfregi ;
1205
1250
1251
+ bfregi = & context -> bfregi ;
1206
1252
if (MLX5_CAP_GEN (dev -> mdev , log_max_transport_domain ))
1207
1253
mlx5_core_dealloc_transport_domain (dev -> mdev , context -> tdn );
1208
1254
1209
1255
free_page (context -> upd_xlt_page );
1210
-
1211
- for (i = 0 ; i < bfregi -> num_uars ; i ++ ) {
1212
- if (mlx5_cmd_free_uar (dev -> mdev , bfregi -> uars [i ].index ))
1213
- mlx5_ib_warn (dev , "Failed to free UAR 0x%x\n" ,
1214
- bfregi -> uars [i ].index );
1215
- }
1216
-
1256
+ deallocate_uars (dev , context );
1257
+ kfree (bfregi -> sys_pages );
1217
1258
kfree (bfregi -> count );
1218
- kfree (bfregi -> bitmap );
1219
- kfree (bfregi -> uars );
1220
1259
kfree (context );
1221
1260
1222
1261
return 0 ;
1223
1262
}
1224
1263
1225
- static phys_addr_t uar_index2pfn (struct mlx5_ib_dev * dev , int index )
1264
+ static phys_addr_t uar_index2pfn (struct mlx5_ib_dev * dev ,
1265
+ struct mlx5_bfreg_info * bfregi ,
1266
+ int idx )
1226
1267
{
1227
- return (pci_resource_start (dev -> mdev -> pdev , 0 ) >> PAGE_SHIFT ) + index ;
1268
+ int fw_uars_per_page ;
1269
+
1270
+ fw_uars_per_page = MLX5_CAP_GEN (dev -> mdev , uar_4k ) ? MLX5_UARS_IN_PAGE : 1 ;
1271
+
1272
+ return (pci_resource_start (dev -> mdev -> pdev , 0 ) >> PAGE_SHIFT ) +
1273
+ bfregi -> sys_pages [idx ] / fw_uars_per_page ;
1228
1274
}
1229
1275
1230
1276
static int get_command (unsigned long offset )
@@ -1384,6 +1430,18 @@ static int uar_mmap(struct mlx5_ib_dev *dev, enum mlx5_ib_mmap_cmd cmd,
1384
1430
unsigned long idx ;
1385
1431
phys_addr_t pfn , pa ;
1386
1432
pgprot_t prot ;
1433
+ int uars_per_page ;
1434
+
1435
+ if (vma -> vm_end - vma -> vm_start != PAGE_SIZE )
1436
+ return - EINVAL ;
1437
+
1438
+ uars_per_page = get_uars_per_sys_page (dev , bfregi -> lib_uar_4k );
1439
+ idx = get_index (vma -> vm_pgoff );
1440
+ if (idx % uars_per_page ||
1441
+ idx * uars_per_page >= bfregi -> num_sys_pages ) {
1442
+ mlx5_ib_warn (dev , "invalid uar index %lu\n" , idx );
1443
+ return - EINVAL ;
1444
+ }
1387
1445
1388
1446
switch (cmd ) {
1389
1447
case MLX5_IB_MMAP_WC_PAGE :
@@ -1406,14 +1464,7 @@ static int uar_mmap(struct mlx5_ib_dev *dev, enum mlx5_ib_mmap_cmd cmd,
1406
1464
return - EINVAL ;
1407
1465
}
1408
1466
1409
- if (vma -> vm_end - vma -> vm_start != PAGE_SIZE )
1410
- return - EINVAL ;
1411
-
1412
- idx = get_index (vma -> vm_pgoff );
1413
- if (idx >= bfregi -> num_uars )
1414
- return - EINVAL ;
1415
-
1416
- pfn = uar_index2pfn (dev , bfregi -> uars [idx ].index );
1467
+ pfn = uar_index2pfn (dev , bfregi , idx );
1417
1468
mlx5_ib_dbg (dev , "uar idx 0x%lx, pfn %pa\n" , idx , & pfn );
1418
1469
1419
1470
vma -> vm_page_prot = prot ;
0 commit comments