* [PATCH 1/3] libceph: allocate ceph messages with a slab allocator
2013-05-01 21:37 [PATCH 0/3] libceph: use slab caches in messenger and osd osd client Alex Elder
@ 2013-05-01 21:38 ` Alex Elder
2013-05-01 21:38 ` [PATCH 2/3] libceph: allocate ceph message data with a slab Alex Elder
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Alex Elder @ 2013-05-01 21:38 UTC (permalink / raw)
To: ceph-devel
Create a slab cache to manage ceph_msg structure allocation.
This is part of:
http://tracker.ceph.com/issues/3926
Signed-off-by: Alex Elder <elder@inktank.com>
---
net/ceph/messenger.c | 29 +++++++++++++++++++++++++++--
1 file changed, 27 insertions(+), 2 deletions(-)
diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c
index 91dd451..bc1ba4c 100644
--- a/net/ceph/messenger.c
+++ b/net/ceph/messenger.c
@@ -152,6 +152,10 @@ static bool con_flag_test_and_set(struct
ceph_connection *con,
return test_and_set_bit(con_flag, &con->flags);
}
+/* Slab caches for frequently-allocated structures */
+
+static struct kmem_cache *ceph_msg_cache;
+
/* static tag bytes (protocol control messages) */
static char tag_msg = CEPH_MSGR_TAG_MSG;
static char tag_ack = CEPH_MSGR_TAG_ACK;
@@ -226,6 +230,22 @@ static void encode_my_addr(struct ceph_messenger *msgr)
*/
static struct workqueue_struct *ceph_msgr_wq;
+static int ceph_msgr_slab_init(void)
+{
+ BUG_ON(ceph_msg_cache);
+ ceph_msg_cache = kmem_cache_create("ceph_msg",
+ sizeof (struct ceph_msg),
+ __alignof__(struct ceph_msg), 0, NULL);
+ return ceph_msg_cache ? 0 : -ENOMEM;
+}
+
+static void ceph_msgr_slab_exit(void)
+{
+ BUG_ON(!ceph_msg_cache);
+ kmem_cache_destroy(ceph_msg_cache);
+ ceph_msg_cache = NULL;
+}
+
static void _ceph_msgr_exit(void)
{
if (ceph_msgr_wq) {
@@ -233,6 +253,8 @@ static void _ceph_msgr_exit(void)
ceph_msgr_wq = NULL;
}
+ ceph_msgr_slab_exit();
+
BUG_ON(zero_page == NULL);
kunmap(zero_page);
page_cache_release(zero_page);
@@ -245,6 +267,9 @@ int ceph_msgr_init(void)
zero_page = ZERO_PAGE(0);
page_cache_get(zero_page);
+ if (ceph_msgr_slab_init())
+ return -ENOMEM;
+
ceph_msgr_wq = alloc_workqueue("ceph-msgr", WQ_NON_REENTRANT, 0);
if (ceph_msgr_wq)
return 0;
@@ -3068,7 +3093,7 @@ struct ceph_msg *ceph_msg_new(int type, int
front_len, gfp_t flags,
{
struct ceph_msg *m;
- m = kzalloc(sizeof(*m), flags);
+ m = kmem_cache_zalloc(ceph_msg_cache, flags);
if (m == NULL)
goto out;
@@ -3215,7 +3240,7 @@ void ceph_msg_kfree(struct ceph_msg *m)
vfree(m->front.iov_base);
else
kfree(m->front.iov_base);
- kfree(m);
+ kmem_cache_free(ceph_msg_cache, m);
}
/*
--
1.7.9.5
^ permalink raw reply related [flat|nested] 5+ messages in thread* [PATCH 2/3] libceph: allocate ceph message data with a slab
2013-05-01 21:37 [PATCH 0/3] libceph: use slab caches in messenger and osd osd client Alex Elder
2013-05-01 21:38 ` [PATCH 1/3] libceph: allocate ceph messages with a slab allocator Alex Elder
@ 2013-05-01 21:38 ` Alex Elder
2013-05-01 21:38 ` [PATCH 3/3] libceph: use slab cache for osd client requests Alex Elder
2013-05-02 16:35 ` [PATCH 0/3] libceph: use slab caches in messenger and osd osd client Josh Durgin
3 siblings, 0 replies; 5+ messages in thread
From: Alex Elder @ 2013-05-01 21:38 UTC (permalink / raw)
To: ceph-devel
Create a slab cache to manage ceph_msg_data structure allocation.
This is part of:
http://tracker.ceph.com/issues/3926
Signed-off-by: Alex Elder <elder@inktank.com>
---
net/ceph/messenger.c | 26 +++++++++++++++++++++++---
1 file changed, 23 insertions(+), 3 deletions(-)
diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c
index bc1ba4c..eb0a46a 100644
--- a/net/ceph/messenger.c
+++ b/net/ceph/messenger.c
@@ -155,6 +155,7 @@ static bool con_flag_test_and_set(struct
ceph_connection *con,
/* Slab caches for frequently-allocated structures */
static struct kmem_cache *ceph_msg_cache;
+static struct kmem_cache *ceph_msg_data_cache;
/* static tag bytes (protocol control messages) */
static char tag_msg = CEPH_MSGR_TAG_MSG;
@@ -236,11 +237,30 @@ static int ceph_msgr_slab_init(void)
ceph_msg_cache = kmem_cache_create("ceph_msg",
sizeof (struct ceph_msg),
__alignof__(struct ceph_msg), 0, NULL);
- return ceph_msg_cache ? 0 : -ENOMEM;
+
+ if (!ceph_msg_cache)
+ return -ENOMEM;
+
+ BUG_ON(ceph_msg_data_cache);
+ ceph_msg_data_cache = kmem_cache_create("ceph_msg_data",
+ sizeof (struct ceph_msg_data),
+ __alignof__(struct ceph_msg_data),
+ 0, NULL);
+ if (ceph_msg_data_cache)
+ return 0;
+
+ kmem_cache_destroy(ceph_msg_cache);
+ ceph_msg_cache = NULL;
+
+ return -ENOMEM;
}
static void ceph_msgr_slab_exit(void)
{
+ BUG_ON(!ceph_msg_data_cache);
+ kmem_cache_destroy(ceph_msg_data_cache);
+ ceph_msg_data_cache = NULL;
+
BUG_ON(!ceph_msg_cache);
kmem_cache_destroy(ceph_msg_cache);
ceph_msg_cache = NULL;
@@ -3008,7 +3028,7 @@ static struct ceph_msg_data
*ceph_msg_data_create(enum ceph_msg_data_type type)
if (WARN_ON(!ceph_msg_data_type_valid(type)))
return NULL;
- data = kzalloc(sizeof (*data), GFP_NOFS);
+ data = kmem_cache_zalloc(ceph_msg_data_cache, GFP_NOFS);
if (data)
data->type = type;
INIT_LIST_HEAD(&data->links);
@@ -3026,7 +3046,7 @@ static void ceph_msg_data_destroy(struct
ceph_msg_data *data)
ceph_pagelist_release(data->pagelist);
kfree(data->pagelist);
}
- kfree(data);
+ kmem_cache_free(ceph_msg_data_cache, data);
}
void ceph_msg_data_add_pages(struct ceph_msg *msg, struct page **pages,
--
1.7.9.5
^ permalink raw reply related [flat|nested] 5+ messages in thread* [PATCH 3/3] libceph: use slab cache for osd client requests
2013-05-01 21:37 [PATCH 0/3] libceph: use slab caches in messenger and osd osd client Alex Elder
2013-05-01 21:38 ` [PATCH 1/3] libceph: allocate ceph messages with a slab allocator Alex Elder
2013-05-01 21:38 ` [PATCH 2/3] libceph: allocate ceph message data with a slab Alex Elder
@ 2013-05-01 21:38 ` Alex Elder
2013-05-02 16:35 ` [PATCH 0/3] libceph: use slab caches in messenger and osd osd client Josh Durgin
3 siblings, 0 replies; 5+ messages in thread
From: Alex Elder @ 2013-05-01 21:38 UTC (permalink / raw)
To: ceph-devel
Create a slab cache to manage allocation of ceph_osdc_request
structures.
This resolves:
http://tracker.ceph.com/issues/3926
Signed-off-by: Alex Elder <elder@inktank.com>
---
include/linux/ceph/osd_client.h | 3 +++
net/ceph/ceph_common.c | 7 +++++++
net/ceph/osd_client.c | 27 +++++++++++++++++++++++++--
3 files changed, 35 insertions(+), 2 deletions(-)
diff --git a/include/linux/ceph/osd_client.h
b/include/linux/ceph/osd_client.h
index 4191cd2..186db0b 100644
--- a/include/linux/ceph/osd_client.h
+++ b/include/linux/ceph/osd_client.h
@@ -224,6 +224,9 @@ struct ceph_osd_client {
struct workqueue_struct *notify_wq;
};
+extern int ceph_osdc_setup(void);
+extern void ceph_osdc_cleanup(void);
+
extern int ceph_osdc_init(struct ceph_osd_client *osdc,
struct ceph_client *client);
extern void ceph_osdc_stop(struct ceph_osd_client *osdc);
diff --git a/net/ceph/ceph_common.c b/net/ceph/ceph_common.c
index c5605ae..b746cd7 100644
--- a/net/ceph/ceph_common.c
+++ b/net/ceph/ceph_common.c
@@ -601,11 +601,17 @@ static int __init init_ceph_lib(void)
if (ret < 0)
goto out_crypto;
+ ret = ceph_osdc_setup();
+ if (ret < 0)
+ goto out_msgr;
+
pr_info("loaded (mon/osd proto %d/%d)\n",
CEPH_MONC_PROTOCOL, CEPH_OSDC_PROTOCOL);
return 0;
+out_msgr:
+ ceph_msgr_exit();
out_crypto:
ceph_crypto_shutdown();
out_debugfs:
@@ -617,6 +623,7 @@ out:
static void __exit exit_ceph_lib(void)
{
dout("exit_ceph_lib\n");
+ ceph_osdc_cleanup();
ceph_msgr_exit();
ceph_crypto_shutdown();
ceph_debugfs_cleanup();
diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c
index 57d8db5..a3395fd 100644
--- a/net/ceph/osd_client.c
+++ b/net/ceph/osd_client.c
@@ -22,6 +22,8 @@
#define OSD_OP_FRONT_LEN 4096
#define OSD_OPREPLY_FRONT_LEN 512
+static struct kmem_cache *ceph_osd_request_cache;
+
static const struct ceph_connection_operations osd_con_ops;
static void __send_queued(struct ceph_osd_client *osdc);
@@ -315,7 +317,8 @@ void ceph_osdc_release_request(struct kref *kref)
if (req->r_mempool)
mempool_free(req, req->r_osdc->req_mempool);
else
- kfree(req);
+ kmem_cache_free(ceph_osd_request_cache, req);
+
}
EXPORT_SYMBOL(ceph_osdc_release_request);
@@ -346,7 +349,7 @@ struct ceph_osd_request
*ceph_osdc_alloc_request(struct ceph_osd_client *osdc,
req = mempool_alloc(osdc->req_mempool, gfp_flags);
memset(req, 0, sizeof(*req));
} else {
- req = kzalloc(sizeof(*req), gfp_flags);
+ req = kmem_cache_zalloc(ceph_osd_request_cache, gfp_flags);
}
if (req == NULL)
return NULL;
@@ -2365,6 +2368,26 @@ int ceph_osdc_writepages(struct ceph_osd_client
*osdc, struct ceph_vino vino,
}
EXPORT_SYMBOL(ceph_osdc_writepages);
+int ceph_osdc_setup(void)
+{
+ BUG_ON(ceph_osd_request_cache);
+ ceph_osd_request_cache = kmem_cache_create("ceph_osd_request",
+ sizeof (struct ceph_osd_request),
+ __alignof__(struct ceph_osd_request),
+ 0, NULL);
+
+ return ceph_osd_request_cache ? 0 : -ENOMEM;
+}
+EXPORT_SYMBOL(ceph_osdc_setup);
+
+void ceph_osdc_cleanup(void)
+{
+ BUG_ON(!ceph_osd_request_cache);
+ kmem_cache_destroy(ceph_osd_request_cache);
+ ceph_osd_request_cache = NULL;
+}
+EXPORT_SYMBOL(ceph_osdc_cleanup);
+
/*
* handle incoming message
*/
--
1.7.9.5
^ permalink raw reply related [flat|nested] 5+ messages in thread* Re: [PATCH 0/3] libceph: use slab caches in messenger and osd osd client
2013-05-01 21:37 [PATCH 0/3] libceph: use slab caches in messenger and osd osd client Alex Elder
` (2 preceding siblings ...)
2013-05-01 21:38 ` [PATCH 3/3] libceph: use slab cache for osd client requests Alex Elder
@ 2013-05-02 16:35 ` Josh Durgin
3 siblings, 0 replies; 5+ messages in thread
From: Josh Durgin @ 2013-05-02 16:35 UTC (permalink / raw)
To: Alex Elder; +Cc: ceph-devel
On 05/01/2013 02:37 PM, Alex Elder wrote:
> This series adds slab caches to some frequently-allocated
> data structures in the messenger and the osd client.
>
> -Alex
>
> [PATCH 1/3] libceph: allocate ceph messages with a slab allocator
> [PATCH 2/3] libceph: allocate ceph message data with a slab
> [PATCH 3/3] libceph: use slab cache for osd client requests
These all look good.
Reviewed-by: Josh Durgin <josh.durgin@inktank.com>
^ permalink raw reply [flat|nested] 5+ messages in thread