@@ -86,7 +86,9 @@ struct mlx5_modify_raw_qp_param {
86
86
u16 operation ;
87
87
88
88
u32 set_mask ; /* raw_qp_set_mask_map */
89
- u32 rate_limit ;
89
+
90
+ struct mlx5_rate_limit rl ;
91
+
90
92
u8 rq_q_ctr_id ;
91
93
};
92
94
@@ -2774,8 +2776,9 @@ static int modify_raw_packet_qp_sq(struct mlx5_core_dev *dev,
2774
2776
const struct mlx5_modify_raw_qp_param * raw_qp_param )
2775
2777
{
2776
2778
struct mlx5_ib_qp * ibqp = sq -> base .container_mibqp ;
2777
- u32 old_rate = ibqp -> rate_limit ;
2778
- u32 new_rate = old_rate ;
2779
+ struct mlx5_rate_limit old_rl = ibqp -> rl ;
2780
+ struct mlx5_rate_limit new_rl = old_rl ;
2781
+ bool new_rate_added = false;
2779
2782
u16 rl_index = 0 ;
2780
2783
void * in ;
2781
2784
void * sqc ;
@@ -2797,39 +2800,43 @@ static int modify_raw_packet_qp_sq(struct mlx5_core_dev *dev,
2797
2800
pr_warn ("%s: Rate limit can only be changed when SQ is moving to RDY\n" ,
2798
2801
__func__ );
2799
2802
else
2800
- new_rate = raw_qp_param -> rate_limit ;
2803
+ new_rl = raw_qp_param -> rl ;
2801
2804
}
2802
2805
2803
- if (old_rate != new_rate ) {
2804
- if (new_rate ) {
2805
- err = mlx5_rl_add_rate (dev , new_rate , & rl_index );
2806
+ if (! mlx5_rl_are_equal ( & old_rl , & new_rl ) ) {
2807
+ if (new_rl . rate ) {
2808
+ err = mlx5_rl_add_rate (dev , & rl_index , & new_rl );
2806
2809
if (err ) {
2807
- pr_err ("Failed configuring rate %u: %d\n" ,
2808
- new_rate , err );
2810
+ pr_err ("Failed configuring rate limit(err %d): \
2811
+ rate %u, max_burst_sz %u, typical_pkt_sz %u\n" ,
2812
+ err , new_rl .rate , new_rl .max_burst_sz ,
2813
+ new_rl .typical_pkt_sz );
2814
+
2809
2815
goto out ;
2810
2816
}
2817
+ new_rate_added = true;
2811
2818
}
2812
2819
2813
2820
MLX5_SET64 (modify_sq_in , in , modify_bitmask , 1 );
2821
+ /* index 0 means no limit */
2814
2822
MLX5_SET (sqc , sqc , packet_pacing_rate_limit_index , rl_index );
2815
2823
}
2816
2824
2817
2825
err = mlx5_core_modify_sq (dev , sq -> base .mqp .qpn , in , inlen );
2818
2826
if (err ) {
2819
2827
/* Remove new rate from table if failed */
2820
- if (new_rate &&
2821
- old_rate != new_rate )
2822
- mlx5_rl_remove_rate (dev , new_rate );
2828
+ if (new_rate_added )
2829
+ mlx5_rl_remove_rate (dev , & new_rl );
2823
2830
goto out ;
2824
2831
}
2825
2832
2826
2833
/* Only remove the old rate after new rate was set */
2827
- if ((old_rate &&
2828
- ( old_rate != new_rate )) ||
2834
+ if ((old_rl . rate &&
2835
+ ! mlx5_rl_are_equal ( & old_rl , & new_rl )) ||
2829
2836
(new_state != MLX5_SQC_STATE_RDY ))
2830
- mlx5_rl_remove_rate (dev , old_rate );
2837
+ mlx5_rl_remove_rate (dev , & old_rl );
2831
2838
2832
- ibqp -> rate_limit = new_rate ;
2839
+ ibqp -> rl = new_rl ;
2833
2840
sq -> state = new_state ;
2834
2841
2835
2842
out :
@@ -2906,7 +2913,8 @@ static int modify_raw_packet_qp(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp,
2906
2913
2907
2914
static int __mlx5_ib_modify_qp (struct ib_qp * ibqp ,
2908
2915
const struct ib_qp_attr * attr , int attr_mask ,
2909
- enum ib_qp_state cur_state , enum ib_qp_state new_state )
2916
+ enum ib_qp_state cur_state , enum ib_qp_state new_state ,
2917
+ const struct mlx5_ib_modify_qp * ucmd )
2910
2918
{
2911
2919
static const u16 optab [MLX5_QP_NUM_STATE ][MLX5_QP_NUM_STATE ] = {
2912
2920
[MLX5_QP_STATE_RST ] = {
@@ -3144,7 +3152,30 @@ static int __mlx5_ib_modify_qp(struct ib_qp *ibqp,
3144
3152
}
3145
3153
3146
3154
if (attr_mask & IB_QP_RATE_LIMIT ) {
3147
- raw_qp_param .rate_limit = attr -> rate_limit ;
3155
+ raw_qp_param .rl .rate = attr -> rate_limit ;
3156
+
3157
+ if (ucmd -> burst_info .max_burst_sz ) {
3158
+ if (attr -> rate_limit &&
3159
+ MLX5_CAP_QOS (dev -> mdev , packet_pacing_burst_bound )) {
3160
+ raw_qp_param .rl .max_burst_sz =
3161
+ ucmd -> burst_info .max_burst_sz ;
3162
+ } else {
3163
+ err = - EINVAL ;
3164
+ goto out ;
3165
+ }
3166
+ }
3167
+
3168
+ if (ucmd -> burst_info .typical_pkt_sz ) {
3169
+ if (attr -> rate_limit &&
3170
+ MLX5_CAP_QOS (dev -> mdev , packet_pacing_typical_size )) {
3171
+ raw_qp_param .rl .typical_pkt_sz =
3172
+ ucmd -> burst_info .typical_pkt_sz ;
3173
+ } else {
3174
+ err = - EINVAL ;
3175
+ goto out ;
3176
+ }
3177
+ }
3178
+
3148
3179
raw_qp_param .set_mask |= MLX5_RAW_QP_RATE_LIMIT ;
3149
3180
}
3150
3181
@@ -3332,15 +3363,39 @@ int mlx5_ib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
3332
3363
{
3333
3364
struct mlx5_ib_dev * dev = to_mdev (ibqp -> device );
3334
3365
struct mlx5_ib_qp * qp = to_mqp (ibqp );
3366
+ struct mlx5_ib_modify_qp ucmd = {};
3335
3367
enum ib_qp_type qp_type ;
3336
3368
enum ib_qp_state cur_state , new_state ;
3369
+ size_t required_cmd_sz ;
3337
3370
int err = - EINVAL ;
3338
3371
int port ;
3339
3372
enum rdma_link_layer ll = IB_LINK_LAYER_UNSPECIFIED ;
3340
3373
3341
3374
if (ibqp -> rwq_ind_tbl )
3342
3375
return - ENOSYS ;
3343
3376
3377
+ if (udata && udata -> inlen ) {
3378
+ required_cmd_sz = offsetof(typeof (ucmd ), reserved ) +
3379
+ sizeof (ucmd .reserved );
3380
+ if (udata -> inlen < required_cmd_sz )
3381
+ return - EINVAL ;
3382
+
3383
+ if (udata -> inlen > sizeof (ucmd ) &&
3384
+ !ib_is_udata_cleared (udata , sizeof (ucmd ),
3385
+ udata -> inlen - sizeof (ucmd )))
3386
+ return - EOPNOTSUPP ;
3387
+
3388
+ if (ib_copy_from_udata (& ucmd , udata ,
3389
+ min (udata -> inlen , sizeof (ucmd ))))
3390
+ return - EFAULT ;
3391
+
3392
+ if (ucmd .comp_mask ||
3393
+ memchr_inv (& ucmd .reserved , 0 , sizeof (ucmd .reserved )) ||
3394
+ memchr_inv (& ucmd .burst_info .reserved , 0 ,
3395
+ sizeof (ucmd .burst_info .reserved )))
3396
+ return - EOPNOTSUPP ;
3397
+ }
3398
+
3344
3399
if (unlikely (ibqp -> qp_type == IB_QPT_GSI ))
3345
3400
return mlx5_ib_gsi_modify_qp (ibqp , attr , attr_mask );
3346
3401
@@ -3421,7 +3476,8 @@ int mlx5_ib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
3421
3476
goto out ;
3422
3477
}
3423
3478
3424
- err = __mlx5_ib_modify_qp (ibqp , attr , attr_mask , cur_state , new_state );
3479
+ err = __mlx5_ib_modify_qp (ibqp , attr , attr_mask , cur_state ,
3480
+ new_state , & ucmd );
3425
3481
3426
3482
out :
3427
3483
mutex_unlock (& qp -> mutex );
0 commit comments