@@ -2649,8 +2649,11 @@ static int irdma_hw_alloc_stag(struct irdma_device *iwdev,
26492649 cqp_info -> in .u .alloc_stag .scratch = (uintptr_t )cqp_request ;
26502650 status = irdma_handle_cqp_op (iwdev -> rf , cqp_request );
26512651 irdma_put_cqp_request (& iwdev -> rf -> cqp , cqp_request );
2652+ if (status )
2653+ return status ;
26522654
2653- return status ;
2655+ iwmr -> is_hwreg = 1 ;
2656+ return 0 ;
26542657}
26552658
26562659/**
@@ -2816,14 +2819,18 @@ static int irdma_hwreg_mr(struct irdma_device *iwdev, struct irdma_mr *iwmr,
28162819 ret = irdma_handle_cqp_op (iwdev -> rf , cqp_request );
28172820 irdma_put_cqp_request (& iwdev -> rf -> cqp , cqp_request );
28182821
2822+ if (!ret )
2823+ iwmr -> is_hwreg = 1 ;
2824+
28192825 return ret ;
28202826}
28212827
2822- static int irdma_reg_user_mr_type_mem (struct irdma_mr * iwmr , int access )
2828+ static int irdma_reg_user_mr_type_mem (struct irdma_mr * iwmr , int access ,
2829+ bool create_stag )
28232830{
28242831 struct irdma_device * iwdev = to_iwdev (iwmr -> ibmr .device );
28252832 struct irdma_pbl * iwpbl = & iwmr -> iwpbl ;
2826- u32 stag ;
2833+ u32 stag = 0 ;
28272834 u8 lvl ;
28282835 int err ;
28292836
@@ -2842,23 +2849,27 @@ static int irdma_reg_user_mr_type_mem(struct irdma_mr *iwmr, int access)
28422849 }
28432850 }
28442851
2845- stag = irdma_create_stag (iwdev );
2846- if (!stag ) {
2847- err = - ENOMEM ;
2848- goto free_pble ;
2852+ if (create_stag ) {
2853+ stag = irdma_create_stag (iwdev );
2854+ if (!stag ) {
2855+ err = - ENOMEM ;
2856+ goto free_pble ;
2857+ }
2858+
2859+ iwmr -> stag = stag ;
2860+ iwmr -> ibmr .rkey = stag ;
2861+ iwmr -> ibmr .lkey = stag ;
28492862 }
28502863
2851- iwmr -> stag = stag ;
2852- iwmr -> ibmr .rkey = stag ;
2853- iwmr -> ibmr .lkey = stag ;
28542864 err = irdma_hwreg_mr (iwdev , iwmr , access );
28552865 if (err )
28562866 goto err_hwreg ;
28572867
28582868 return 0 ;
28592869
28602870err_hwreg :
2861- irdma_free_stag (iwdev , stag );
2871+ if (stag )
2872+ irdma_free_stag (iwdev , stag );
28622873
28632874free_pble :
28642875 if (iwpbl -> pble_alloc .level != PBLE_LEVEL_0 && iwpbl -> pbl_allocated )
@@ -3033,7 +3044,7 @@ static struct ib_mr *irdma_reg_user_mr(struct ib_pd *pd, u64 start, u64 len,
30333044 goto error ;
30343045 break ;
30353046 case IRDMA_MEMREG_TYPE_MEM :
3036- err = irdma_reg_user_mr_type_mem (iwmr , access );
3047+ err = irdma_reg_user_mr_type_mem (iwmr , access , true );
30373048 if (err )
30383049 goto error ;
30393050
@@ -3077,7 +3088,7 @@ static struct ib_mr *irdma_reg_user_mr_dmabuf(struct ib_pd *pd, u64 start,
30773088 goto err_release ;
30783089 }
30793090
3080- err = irdma_reg_user_mr_type_mem (iwmr , access );
3091+ err = irdma_reg_user_mr_type_mem (iwmr , access , true );
30813092 if (err )
30823093 goto err_iwmr ;
30833094
@@ -3092,6 +3103,161 @@ static struct ib_mr *irdma_reg_user_mr_dmabuf(struct ib_pd *pd, u64 start,
30923103 return ERR_PTR (err );
30933104}
30943105
3106+ static int irdma_hwdereg_mr (struct ib_mr * ib_mr )
3107+ {
3108+ struct irdma_device * iwdev = to_iwdev (ib_mr -> device );
3109+ struct irdma_mr * iwmr = to_iwmr (ib_mr );
3110+ struct irdma_pd * iwpd = to_iwpd (ib_mr -> pd );
3111+ struct irdma_dealloc_stag_info * info ;
3112+ struct irdma_pbl * iwpbl = & iwmr -> iwpbl ;
3113+ struct irdma_cqp_request * cqp_request ;
3114+ struct cqp_cmds_info * cqp_info ;
3115+ int status ;
3116+
3117+ /* Skip HW MR de-register when it is already de-registered
3118+ * during an MR re-reregister and the re-registration fails
3119+ */
3120+ if (!iwmr -> is_hwreg )
3121+ return 0 ;
3122+
3123+ cqp_request = irdma_alloc_and_get_cqp_request (& iwdev -> rf -> cqp , true);
3124+ if (!cqp_request )
3125+ return - ENOMEM ;
3126+
3127+ cqp_info = & cqp_request -> info ;
3128+ info = & cqp_info -> in .u .dealloc_stag .info ;
3129+ memset (info , 0 , sizeof (* info ));
3130+ info -> pd_id = iwpd -> sc_pd .pd_id ;
3131+ info -> stag_idx = ib_mr -> rkey >> IRDMA_CQPSQ_STAG_IDX_S ;
3132+ info -> mr = true;
3133+ if (iwpbl -> pbl_allocated )
3134+ info -> dealloc_pbl = true;
3135+
3136+ cqp_info -> cqp_cmd = IRDMA_OP_DEALLOC_STAG ;
3137+ cqp_info -> post_sq = 1 ;
3138+ cqp_info -> in .u .dealloc_stag .dev = & iwdev -> rf -> sc_dev ;
3139+ cqp_info -> in .u .dealloc_stag .scratch = (uintptr_t )cqp_request ;
3140+ status = irdma_handle_cqp_op (iwdev -> rf , cqp_request );
3141+ irdma_put_cqp_request (& iwdev -> rf -> cqp , cqp_request );
3142+ if (status )
3143+ return status ;
3144+
3145+ iwmr -> is_hwreg = 0 ;
3146+ return 0 ;
3147+ }
3148+
3149+ /*
3150+ * irdma_rereg_mr_trans - Re-register a user MR for a change translation.
3151+ * @iwmr: ptr of iwmr
3152+ * @start: virtual start address
3153+ * @len: length of mr
3154+ * @virt: virtual address
3155+ *
3156+ * Re-register a user memory region when a change translation is requested.
3157+ * Re-register a new region while reusing the stag from the original registration.
3158+ */
3159+ static int irdma_rereg_mr_trans (struct irdma_mr * iwmr , u64 start , u64 len ,
3160+ u64 virt )
3161+ {
3162+ struct irdma_device * iwdev = to_iwdev (iwmr -> ibmr .device );
3163+ struct irdma_pbl * iwpbl = & iwmr -> iwpbl ;
3164+ struct ib_pd * pd = iwmr -> ibmr .pd ;
3165+ struct ib_umem * region ;
3166+ int err ;
3167+
3168+ region = ib_umem_get (pd -> device , start , len , iwmr -> access );
3169+ if (IS_ERR (region ))
3170+ return PTR_ERR (region );
3171+
3172+ iwmr -> region = region ;
3173+ iwmr -> ibmr .iova = virt ;
3174+ iwmr -> ibmr .pd = pd ;
3175+ iwmr -> page_size = ib_umem_find_best_pgsz (region ,
3176+ iwdev -> rf -> sc_dev .hw_attrs .page_size_cap ,
3177+ virt );
3178+ if (unlikely (!iwmr -> page_size )) {
3179+ err = - EOPNOTSUPP ;
3180+ goto err ;
3181+ }
3182+
3183+ iwmr -> len = region -> length ;
3184+ iwpbl -> user_base = virt ;
3185+ iwmr -> page_cnt = ib_umem_num_dma_blocks (region , iwmr -> page_size );
3186+
3187+ err = irdma_reg_user_mr_type_mem (iwmr , iwmr -> access , false);
3188+ if (err )
3189+ goto err ;
3190+
3191+ return 0 ;
3192+
3193+ err :
3194+ ib_umem_release (region );
3195+ return err ;
3196+ }
3197+
3198+ /*
3199+ * irdma_rereg_user_mr - Re-Register a user memory region(MR)
3200+ * @ibmr: ib mem to access iwarp mr pointer
3201+ * @flags: bit mask to indicate which of the attr's of MR modified
3202+ * @start: virtual start address
3203+ * @len: length of mr
3204+ * @virt: virtual address
3205+ * @new_access: bit mask of access flags
3206+ * @new_pd: ptr of pd
3207+ * @udata: user data
3208+ *
3209+ * Return:
3210+ * NULL - Success, existing MR updated
3211+ * ERR_PTR - error occurred
3212+ */
3213+ static struct ib_mr * irdma_rereg_user_mr (struct ib_mr * ib_mr , int flags ,
3214+ u64 start , u64 len , u64 virt ,
3215+ int new_access , struct ib_pd * new_pd ,
3216+ struct ib_udata * udata )
3217+ {
3218+ struct irdma_device * iwdev = to_iwdev (ib_mr -> device );
3219+ struct irdma_mr * iwmr = to_iwmr (ib_mr );
3220+ struct irdma_pbl * iwpbl = & iwmr -> iwpbl ;
3221+ int ret ;
3222+
3223+ if (len > iwdev -> rf -> sc_dev .hw_attrs .max_mr_size )
3224+ return ERR_PTR (- EINVAL );
3225+
3226+ if (flags & ~(IB_MR_REREG_TRANS | IB_MR_REREG_PD | IB_MR_REREG_ACCESS ))
3227+ return ERR_PTR (- EOPNOTSUPP );
3228+
3229+ ret = irdma_hwdereg_mr (ib_mr );
3230+ if (ret )
3231+ return ERR_PTR (ret );
3232+
3233+ if (flags & IB_MR_REREG_ACCESS )
3234+ iwmr -> access = new_access ;
3235+
3236+ if (flags & IB_MR_REREG_PD ) {
3237+ iwmr -> ibmr .pd = new_pd ;
3238+ iwmr -> ibmr .device = new_pd -> device ;
3239+ }
3240+
3241+ if (flags & IB_MR_REREG_TRANS ) {
3242+ if (iwpbl -> pbl_allocated ) {
3243+ irdma_free_pble (iwdev -> rf -> pble_rsrc ,
3244+ & iwpbl -> pble_alloc );
3245+ iwpbl -> pbl_allocated = false;
3246+ }
3247+ if (iwmr -> region ) {
3248+ ib_umem_release (iwmr -> region );
3249+ iwmr -> region = NULL ;
3250+ }
3251+
3252+ ret = irdma_rereg_mr_trans (iwmr , start , len , virt );
3253+ } else
3254+ ret = irdma_hwreg_mr (iwdev , iwmr , iwmr -> access );
3255+ if (ret )
3256+ return ERR_PTR (ret );
3257+
3258+ return NULL ;
3259+ }
3260+
30953261/**
30963262 * irdma_reg_phys_mr - register kernel physical memory
30973263 * @pd: ibpd pointer
@@ -3199,16 +3365,10 @@ static void irdma_del_memlist(struct irdma_mr *iwmr,
31993365 */
32003366static int irdma_dereg_mr (struct ib_mr * ib_mr , struct ib_udata * udata )
32013367{
3202- struct ib_pd * ibpd = ib_mr -> pd ;
3203- struct irdma_pd * iwpd = to_iwpd (ibpd );
32043368 struct irdma_mr * iwmr = to_iwmr (ib_mr );
32053369 struct irdma_device * iwdev = to_iwdev (ib_mr -> device );
3206- struct irdma_dealloc_stag_info * info ;
32073370 struct irdma_pbl * iwpbl = & iwmr -> iwpbl ;
3208- struct irdma_pble_alloc * palloc = & iwpbl -> pble_alloc ;
3209- struct irdma_cqp_request * cqp_request ;
3210- struct cqp_cmds_info * cqp_info ;
3211- int status ;
3371+ int ret ;
32123372
32133373 if (iwmr -> type != IRDMA_MEMREG_TYPE_MEM ) {
32143374 if (iwmr -> region ) {
@@ -3222,33 +3382,18 @@ static int irdma_dereg_mr(struct ib_mr *ib_mr, struct ib_udata *udata)
32223382 goto done ;
32233383 }
32243384
3225- cqp_request = irdma_alloc_and_get_cqp_request (& iwdev -> rf -> cqp , true);
3226- if (!cqp_request )
3227- return - ENOMEM ;
3228-
3229- cqp_info = & cqp_request -> info ;
3230- info = & cqp_info -> in .u .dealloc_stag .info ;
3231- memset (info , 0 , sizeof (* info ));
3232- info -> pd_id = iwpd -> sc_pd .pd_id ;
3233- info -> stag_idx = ib_mr -> rkey >> IRDMA_CQPSQ_STAG_IDX_S ;
3234- info -> mr = true;
3235- if (iwpbl -> pbl_allocated )
3236- info -> dealloc_pbl = true;
3237-
3238- cqp_info -> cqp_cmd = IRDMA_OP_DEALLOC_STAG ;
3239- cqp_info -> post_sq = 1 ;
3240- cqp_info -> in .u .dealloc_stag .dev = & iwdev -> rf -> sc_dev ;
3241- cqp_info -> in .u .dealloc_stag .scratch = (uintptr_t )cqp_request ;
3242- status = irdma_handle_cqp_op (iwdev -> rf , cqp_request );
3243- irdma_put_cqp_request (& iwdev -> rf -> cqp , cqp_request );
3244- if (status )
3245- return status ;
3385+ ret = irdma_hwdereg_mr (ib_mr );
3386+ if (ret )
3387+ return ret ;
32463388
32473389 irdma_free_stag (iwdev , iwmr -> stag );
32483390done :
32493391 if (iwpbl -> pbl_allocated )
3250- irdma_free_pble (iwdev -> rf -> pble_rsrc , palloc );
3251- ib_umem_release (iwmr -> region );
3392+ irdma_free_pble (iwdev -> rf -> pble_rsrc , & iwpbl -> pble_alloc );
3393+
3394+ if (iwmr -> region )
3395+ ib_umem_release (iwmr -> region );
3396+
32523397 kfree (iwmr );
32533398
32543399 return 0 ;
@@ -4578,6 +4723,7 @@ static const struct ib_device_ops irdma_dev_ops = {
45784723 .query_qp = irdma_query_qp ,
45794724 .reg_user_mr = irdma_reg_user_mr ,
45804725 .reg_user_mr_dmabuf = irdma_reg_user_mr_dmabuf ,
4726+ .rereg_user_mr = irdma_rereg_user_mr ,
45814727 .req_notify_cq = irdma_req_notify_cq ,
45824728 .resize_cq = irdma_resize_cq ,
45834729 INIT_RDMA_OBJ_SIZE (ib_pd , irdma_pd , ibpd ),
0 commit comments