Sometimes osp cancels very large cookie list with 64K elements.
In this case osp_sync_process_committed() tries to allocate 64 pages
and uses vmalloc.
The fix limits memory allocation size to 4 page with kmalloc, and
reuse it in a loop.
HPE-bug-id: LUS-9815
Fixes:
6d7332102 ("LU-11924 osp: combine llog cancel operations")
Signed-off-by: Alexander Boyko <alexander.boyko@hpe.com>
Change-Id: Ic875335a28f78494fdb3cbc4b0145e5a43831ee8
Reviewed-on: https://review.whamcloud.com/43250
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Tested-by: jenkins <devops@whamcloud.com>
Reviewed-by: Andrew Perepechko <andrew.perepechko@hpe.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
struct ptlrpc_request *req;
struct llog_ctxt *ctxt;
struct llog_handle *llh;
struct ptlrpc_request *req;
struct llog_ctxt *ctxt;
struct llog_handle *llh;
LIST_HEAD(list);
struct list_head *le;
struct llog_logid lgid;
LIST_HEAD(list);
struct list_head *le;
struct llog_logid lgid;
list_for_each(le, &list)
count++;
list_for_each(le, &list)
count++;
- if (count > 2)
- OBD_ALLOC_PTR_ARRAY_LARGE(arr, count);
- else
+ if (count > 2) {
+ arr_size = sizeof(int) * count;
+ /* limit cookie array to order 2 */
+ arr_size = arr_size < (PAGE_SIZE * 4) ? arr_size :
+ (PAGE_SIZE * 4);
+ OBD_ALLOC_LARGE(arr, arr_size);
+ } else {
i = 0;
while (!list_empty(&list)) {
struct osp_job_req_args *jra;
i = 0;
while (!list_empty(&list)) {
struct osp_job_req_args *jra;
rc = llog_cat_cancel_records(env, llh, 1,
&jra->jra_lcookie);
if (rc)
rc = llog_cat_cancel_records(env, llh, 1,
&jra->jra_lcookie);
if (rc)
- CERROR("%s: can't cancel record: %d\n",
+ CERROR("%s: can't cancel record: rc = %d\n",
obd->obd_name, rc);
}
} else {
obd->obd_name, rc);
}
} else {
}
ptlrpc_req_finished(req);
done++;
}
ptlrpc_req_finished(req);
done++;
+ if (arr &&
+ ((i * sizeof(int)) == arr_size ||
+ (list_empty(&list) && i > 0))) {
+ rc = llog_cat_cancel_arr_rec(env, llh, &lgid, i, arr);
+
+ if (rc)
+ CERROR("%s: can't cancel %d records: rc = %d\n",
+ obd->obd_name, i, rc);
+ else
+ CDEBUG(D_OTHER, "%s: massive records cancel id "DFID" num %d\n",
+ obd->obd_name, PFID(&lgid.lgl_oi.oi_fid),
+ i);
+ i = 0;
+ }
+
- if (arr && i > 0) {
- rc = llog_cat_cancel_arr_rec(env, llh, &lgid, i, arr);
-
- if (rc)
- CERROR("%s: can't cancel %d records rc: %d\n",
- obd->obd_name, i, rc);
- else
- CDEBUG(D_OTHER, "%s: massive records cancel id "DFID\
- " num %d\n", obd->obd_name,
- PFID(&lgid.lgl_oi.oi_fid), i);
- }
- OBD_FREE_PTR_ARRAY_LARGE(arr, count);
+ OBD_FREE_LARGE(arr, arr_size);