Add rpc_cache for allocating ptlrpc_requests.
Xyratex-bug-id: MRP-689
Signed-off-by: Andriy Skulysh <Andriy_Skulysh@xyratex.com>
Signed-off-by: Niu Yawei <yawei.niu@intel.com>
Change-Id: I9e442f8309d19b3320727c3fbfcd7de371032369
Reviewed-on: http://review.whamcloud.com/6874
Tested-by: Hudson
Reviewed-by: Andreas Dilger <andreas.dilger@intel.com>
Tested-by: Maloo <whamcloud.maloo@gmail.com>
Reviewed-by: Lai Siyao <lai.siyao@intel.com>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
RETURN(rc);
}
+struct kmem_cache *request_cache;
+
+int ptlrpc_request_cache_init()
+{
+ request_cache = kmem_cache_create("ptlrpc_cache",
+ sizeof(struct ptlrpc_request),
+ 0, SLAB_HWCACHE_ALIGN, NULL);
+ return request_cache == NULL ? -ENOMEM : 0;
+}
+
+void ptlrpc_request_cache_fini()
+{
+ kmem_cache_destroy(request_cache);
+}
+
+struct ptlrpc_request *ptlrpc_request_cache_alloc(int flags)
+{
+ struct ptlrpc_request *req;
+
+ OBD_SLAB_ALLOC_PTR_GFP(req, request_cache, flags);
+ return req;
+}
+
+void ptlrpc_request_cache_free(struct ptlrpc_request *req)
+{
+ OBD_SLAB_FREE_PTR(req, request_cache);
+}
+
/**
* Wind down request pool \a pool.
* Frees all requests from the pool too
LASSERT(req->rq_reqbuf);
LASSERT(req->rq_reqbuf_len == pool->prp_rq_size);
OBD_FREE_LARGE(req->rq_reqbuf, pool->prp_rq_size);
- OBD_FREE(req, sizeof(*req));
+ ptlrpc_request_cache_free(req);
}
spin_unlock(&pool->prp_lock);
OBD_FREE(pool, sizeof(*pool));
struct lustre_msg *msg;
spin_unlock(&pool->prp_lock);
- OBD_ALLOC(req, sizeof(struct ptlrpc_request));
- if (!req)
- return;
- OBD_ALLOC_LARGE(msg, size);
- if (!msg) {
- OBD_FREE(req, sizeof(struct ptlrpc_request));
- return;
+ req = ptlrpc_request_cache_alloc(__GFP_IO);
+ if (!req)
+ return;
+ OBD_ALLOC_LARGE(msg, size);
+ if (!msg) {
+ ptlrpc_request_cache_free(req);
+ return;
}
req->rq_reqbuf = msg;
req->rq_reqbuf_len = size;
struct ptlrpc_request *__ptlrpc_request_alloc(struct obd_import *imp,
struct ptlrpc_request_pool *pool)
{
- struct ptlrpc_request *request = NULL;
+ struct ptlrpc_request *request = NULL;
- if (pool)
- request = ptlrpc_prep_req_from_pool(pool);
+ if (pool)
+ request = ptlrpc_prep_req_from_pool(pool);
- if (!request)
- OBD_ALLOC_PTR(request);
+ if (!request)
+ request = ptlrpc_request_cache_alloc(__GFP_IO);
if (request) {
LASSERTF((unsigned long)imp > 0x1000, "%p", imp);
*/
void ptlrpc_request_free(struct ptlrpc_request *request)
{
- if (request->rq_pool)
- __ptlrpc_free_req_to_pool(request);
- else
- OBD_FREE_PTR(request);
+ if (request->rq_pool)
+ __ptlrpc_free_req_to_pool(request);
+ else
+ ptlrpc_request_cache_free(request);
}
EXPORT_SYMBOL(ptlrpc_request_free);
if (request->rq_pool)
__ptlrpc_free_req_to_pool(request);
else
- OBD_FREE(request, sizeof(*request));
- EXIT;
+ ptlrpc_request_cache_free(request);
+ EXIT;
}
static int __ptlrpc_req_finished(struct ptlrpc_request *request, int locked);
RETURN(ERR_PTR(-EINVAL));
/* copy some code from deprecated fakereq. */
- OBD_ALLOC_PTR(req);
+ req = ptlrpc_request_cache_alloc(__GFP_IO);
if (req == NULL) {
CERROR("ptlrpc: run out of memory!\n");
RETURN(ERR_PTR(-ENOMEM));
/* We moaned above already... */
return;
}
- OBD_ALLOC_GFP(req, sizeof(*req), ALLOC_ATOMIC_TRY);
+ req = ptlrpc_request_cache_alloc(ALLOC_ATOMIC_TRY);
if (req == NULL) {
CERROR("Can't allocate incoming request descriptor: "
"Dropping %s RPC from %s\n",
/* client.c */
struct ptlrpc_bulk_desc *ptlrpc_new_bulk(unsigned npages, unsigned max_brw,
unsigned type, unsigned portal);
+int ptlrpc_request_cache_init(void);
+void ptlrpc_request_cache_fini(void);
+struct ptlrpc_request *ptlrpc_request_cache_alloc(int flags);
+void ptlrpc_request_cache_free(struct ptlrpc_request *req);
void ptlrpc_init_xid(void);
/* events.c */
mutex_init(&ptlrpcd_mutex);
ptlrpc_init_xid();
- rc = req_layout_init();
- if (rc)
- RETURN(rc);
+ rc = req_layout_init();
+ if (rc)
+ RETURN(rc);
- rc = ptlrpc_hr_init();
- if (rc)
- RETURN(rc);
+ rc = ptlrpc_hr_init();
+ if (rc)
+ RETURN(rc);
- cleanup_phase = 1;
+ cleanup_phase = 1;
+ rc = ptlrpc_request_cache_init();
+ if (rc)
+ GOTO(cleanup, rc);
- rc = ptlrpc_init_portals();
- if (rc)
- GOTO(cleanup, rc);
- cleanup_phase = 2;
+ cleanup_phase = 2;
+ rc = ptlrpc_init_portals();
+ if (rc)
+ GOTO(cleanup, rc);
- rc = ptlrpc_connection_init();
- if (rc)
- GOTO(cleanup, rc);
- cleanup_phase = 3;
+ cleanup_phase = 3;
- ptlrpc_put_connection_superhack = ptlrpc_connection_put;
+ rc = ptlrpc_connection_init();
+ if (rc)
+ GOTO(cleanup, rc);
- rc = ptlrpc_start_pinger();
- if (rc)
- GOTO(cleanup, rc);
- cleanup_phase = 4;
+ cleanup_phase = 4;
+ ptlrpc_put_connection_superhack = ptlrpc_connection_put;
- rc = ldlm_init();
- if (rc)
- GOTO(cleanup, rc);
- cleanup_phase = 5;
+ rc = ptlrpc_start_pinger();
+ if (rc)
+ GOTO(cleanup, rc);
- rc = sptlrpc_init();
- if (rc)
- GOTO(cleanup, rc);
+ cleanup_phase = 5;
+ rc = ldlm_init();
+ if (rc)
+ GOTO(cleanup, rc);
+
+ cleanup_phase = 6;
+ rc = sptlrpc_init();
+ if (rc)
+ GOTO(cleanup, rc);
cleanup_phase = 7;
rc = ptlrpc_nrs_init();
ptlrpc_nrs_fini();
#endif
case 7:
- sptlrpc_fini();
- case 5:
- ldlm_exit();
- case 4:
- ptlrpc_stop_pinger();
- case 3:
- ptlrpc_connection_fini();
- case 2:
- ptlrpc_exit_portals();
+ sptlrpc_fini();
+ case 6:
+ ldlm_exit();
+ case 5:
+ ptlrpc_stop_pinger();
+ case 4:
+ ptlrpc_connection_fini();
+ case 3:
+ ptlrpc_exit_portals();
+ case 2:
+ ptlrpc_request_cache_fini();
case 1:
ptlrpc_hr_fini();
req_layout_fini();
ldlm_exit();
ptlrpc_stop_pinger();
ptlrpc_exit_portals();
+ ptlrpc_request_cache_fini();
ptlrpc_hr_fini();
ptlrpc_connection_fini();
}
RETURN(-EACCES);
}
- OBD_ALLOC_PTR(req);
- if (!req)
- RETURN(-ENOMEM);
+ req = ptlrpc_request_cache_alloc(__GFP_IO);
+ if (!req)
+ RETURN(-ENOMEM);
spin_lock_init(&req->rq_lock);
cfs_atomic_set(&req->rq_refcount, 10000);
rc = sptlrpc_req_refresh_ctx(req, 0);
LASSERT(cfs_list_empty(&req->rq_ctx_chain));
sptlrpc_cli_ctx_put(req->rq_cli_ctx, 1);
- OBD_FREE_PTR(req);
+ ptlrpc_request_cache_free(req);
- RETURN(rc);
+ RETURN(rc);
}
/**
int sptlrpc_cli_unwrap_early_reply(struct ptlrpc_request *req,
struct ptlrpc_request **req_ret)
{
- struct ptlrpc_request *early_req;
- char *early_buf;
- int early_bufsz, early_size;
- int rc;
- ENTRY;
+ struct ptlrpc_request *early_req;
+ char *early_buf;
+ int early_bufsz, early_size;
+ int rc;
+ ENTRY;
- OBD_ALLOC_PTR(early_req);
+ early_req = ptlrpc_request_cache_alloc(__GFP_IO);
if (early_req == NULL)
RETURN(-ENOMEM);
err_buf:
OBD_FREE_LARGE(early_buf, early_bufsz);
err_req:
- OBD_FREE_PTR(early_req);
- RETURN(rc);
+ ptlrpc_request_cache_free(early_req);
+ RETURN(rc);
}
/**
*/
void sptlrpc_cli_finish_early_reply(struct ptlrpc_request *early_req)
{
- LASSERT(early_req->rq_repbuf);
- LASSERT(early_req->rq_repdata);
- LASSERT(early_req->rq_repmsg);
+ LASSERT(early_req->rq_repbuf);
+ LASSERT(early_req->rq_repdata);
+ LASSERT(early_req->rq_repmsg);
- sptlrpc_cli_ctx_put(early_req->rq_cli_ctx, 1);
- OBD_FREE_LARGE(early_req->rq_repbuf, early_req->rq_repbuf_len);
- OBD_FREE_PTR(early_req);
+ sptlrpc_cli_ctx_put(early_req->rq_cli_ctx, 1);
+ OBD_FREE_LARGE(early_req->rq_repbuf, early_req->rq_repbuf_len);
+ ptlrpc_request_cache_free(early_req);
}
/**************************************************
sptlrpc_svc_ctx_decref(req);
if (req != &req->rq_rqbd->rqbd_req) {
- /* NB request buffers use an embedded
- * req if the incoming req unlinked the
- * MD; this isn't one of them! */
- OBD_FREE(req, sizeof(*req));
- }
+ /* NB request buffers use an embedded
+ * req if the incoming req unlinked the
+ * MD; this isn't one of them! */
+ ptlrpc_request_cache_free(req);
+ }
}
/**
}
newdl = cfs_time_current_sec() + at_get(&svcpt->scp_at_estimate);
- OBD_ALLOC(reqcopy, sizeof *reqcopy);
- if (reqcopy == NULL)
- RETURN(-ENOMEM);
- OBD_ALLOC_LARGE(reqmsg, req->rq_reqlen);
- if (!reqmsg) {
- OBD_FREE(reqcopy, sizeof *reqcopy);
- RETURN(-ENOMEM);
- }
+ reqcopy = ptlrpc_request_cache_alloc(__GFP_IO);
+ if (reqcopy == NULL)
+ RETURN(-ENOMEM);
+ OBD_ALLOC_LARGE(reqmsg, req->rq_reqlen);
+ if (!reqmsg)
+ GOTO(out_free, rc = -ENOMEM);
*reqcopy = *req;
reqcopy->rq_reply_state = NULL;
out_put:
class_export_rpc_dec(reqcopy->rq_export);
- class_export_put(reqcopy->rq_export);
+ class_export_put(reqcopy->rq_export);
out:
- sptlrpc_svc_ctx_decref(reqcopy);
- OBD_FREE_LARGE(reqmsg, req->rq_reqlen);
- OBD_FREE(reqcopy, sizeof *reqcopy);
- RETURN(rc);
+ sptlrpc_svc_ctx_decref(reqcopy);
+ OBD_FREE_LARGE(reqmsg, req->rq_reqlen);
+out_free:
+ ptlrpc_request_cache_free(reqcopy);
+ RETURN(rc);
}
/* Send early replies to everybody expiring within at_early_margin