summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libglusterfs/src/iobuf.c120
1 files changed, 54 insertions, 66 deletions
diff --git a/libglusterfs/src/iobuf.c b/libglusterfs/src/iobuf.c
index 604dc7072b2..13c8309e670 100644
--- a/libglusterfs/src/iobuf.c
+++ b/libglusterfs/src/iobuf.c
@@ -202,24 +202,15 @@ out:
return NULL;
}
-struct iobuf_arena *
-__iobuf_arena_unprune(struct iobuf_pool *iobuf_pool, size_t page_size)
+static struct iobuf_arena *
+__iobuf_arena_unprune(struct iobuf_pool *iobuf_pool, const size_t page_size,
+ const int index)
{
struct iobuf_arena *iobuf_arena = NULL;
struct iobuf_arena *tmp = NULL;
- int index = 0;
GF_VALIDATE_OR_GOTO("iobuf", iobuf_pool, out);
- index = gf_iobuf_get_arena_index(page_size);
- if (index == -1) {
- gf_msg("iobuf", GF_LOG_ERROR, 0, LG_MSG_PAGE_SIZE_EXCEEDED,
- "page_size (%zu) of iobufs in arena being added is "
- "greater than max available",
- page_size);
- return NULL;
- }
-
list_for_each_entry(tmp, &iobuf_pool->purge[index], list)
{
list_del_init(&tmp->list);
@@ -232,21 +223,11 @@ out:
static struct iobuf_arena *
__iobuf_pool_add_arena(struct iobuf_pool *iobuf_pool, const size_t page_size,
- const int32_t num_pages)
+ const int32_t num_pages, const int index)
{
struct iobuf_arena *iobuf_arena = NULL;
- int index = 0;
- index = gf_iobuf_get_arena_index(page_size);
- if (index == -1) {
- gf_msg("iobuf", GF_LOG_ERROR, 0, LG_MSG_PAGE_SIZE_EXCEEDED,
- "page_size (%zu) of iobufs in arena being added is "
- "greater than max available",
- page_size);
- return NULL;
- }
-
- iobuf_arena = __iobuf_arena_unprune(iobuf_pool, page_size);
+ iobuf_arena = __iobuf_arena_unprune(iobuf_pool, page_size, index);
if (!iobuf_arena) {
iobuf_arena = __iobuf_arena_alloc(iobuf_pool, page_size, num_pages);
@@ -351,6 +332,7 @@ iobuf_pool_new(void)
size_t page_size = 0;
size_t arena_size = 0;
int32_t num_pages = 0;
+ int index;
iobuf_pool = GF_CALLOC(sizeof(*iobuf_pool), 1, gf_common_mt_iobuf_pool);
if (!iobuf_pool)
@@ -379,7 +361,16 @@ iobuf_pool_new(void)
page_size = gf_iobuf_init_config[i].pagesize;
num_pages = gf_iobuf_init_config[i].num_pages;
- __iobuf_pool_add_arena(iobuf_pool, page_size, num_pages);
+ index = gf_iobuf_get_arena_index(page_size);
+ if (index == -1) {
+ gf_msg("iobuf", GF_LOG_ERROR, 0, LG_MSG_PAGE_SIZE_EXCEEDED,
+ "page_size (%zu) of iobufs in arena being added is "
+ "greater than max available",
+ page_size);
+ return NULL;
+ }
+
+ __iobuf_pool_add_arena(iobuf_pool, page_size, num_pages, index);
arena_size += page_size * num_pages;
}
@@ -395,12 +386,10 @@ out:
return iobuf_pool;
}
-void
+static void
__iobuf_arena_prune(struct iobuf_pool *iobuf_pool,
- struct iobuf_arena *iobuf_arena, int index)
+ struct iobuf_arena *iobuf_arena, const int index)
{
- GF_VALIDATE_OR_GOTO("iobuf", iobuf_pool, out);
-
/* code flow comes here only if the arena is in purge list and we can
* free the arena only if we have at least one arena in 'arenas' list
* (ie, at least few iobufs free in arena), that way, there won't
@@ -449,23 +438,13 @@ out:
return;
}
-struct iobuf_arena *
-__iobuf_select_arena(struct iobuf_pool *iobuf_pool, size_t page_size)
+/* Always called under the iobuf_pool mutex lock */
+static struct iobuf_arena *
+__iobuf_select_arena(struct iobuf_pool *iobuf_pool, const size_t page_size,
+ const int index)
{
struct iobuf_arena *iobuf_arena = NULL;
struct iobuf_arena *trav = NULL;
- int index = 0;
-
- GF_VALIDATE_OR_GOTO("iobuf", iobuf_pool, out);
-
- index = gf_iobuf_get_arena_index(page_size);
- if (index == -1) {
- gf_msg("iobuf", GF_LOG_ERROR, 0, LG_MSG_PAGE_SIZE_EXCEEDED,
- "page_size (%zu) of iobufs in arena being added is "
- "greater than max available",
- page_size);
- return NULL;
- }
/* look for unused iobuf from the head-most arena */
list_for_each_entry(trav, &iobuf_pool->arenas[index], list)
@@ -479,21 +458,20 @@ __iobuf_select_arena(struct iobuf_pool *iobuf_pool, size_t page_size)
if (!iobuf_arena) {
/* all arenas were full, find the right count to add */
iobuf_arena = __iobuf_pool_add_arena(
- iobuf_pool, page_size, gf_iobuf_init_config[index].num_pages);
+ iobuf_pool, page_size, gf_iobuf_init_config[index].num_pages,
+ index);
}
-out:
return iobuf_arena;
}
-struct iobuf *
-__iobuf_get(struct iobuf_arena *iobuf_arena, size_t page_size)
+/* iobuf_arena variable is validaed to be non-NULL by all callers */
+static struct iobuf *
+__iobuf_get(struct iobuf_arena *iobuf_arena, const size_t page_size,
+ const int index)
{
struct iobuf *iobuf = NULL;
struct iobuf_pool *iobuf_pool = NULL;
- int index = 0;
-
- GF_VALIDATE_OR_GOTO("iobuf", iobuf_arena, out);
iobuf_pool = iobuf_arena->iobuf_pool;
@@ -512,21 +490,10 @@ __iobuf_get(struct iobuf_arena *iobuf_arena, size_t page_size)
iobuf_arena->max_active = iobuf_arena->active_cnt;
if (iobuf_arena->passive_cnt == 0) {
- index = gf_iobuf_get_arena_index(page_size);
- if (index == -1) {
- gf_msg("iobuf", GF_LOG_ERROR, 0, LG_MSG_PAGE_SIZE_EXCEEDED,
- "page_size (%zu) of"
- " iobufs in arena being added is greater "
- "than max available",
- page_size);
- goto out;
- }
-
list_del(&iobuf_arena->list);
list_add(&iobuf_arena->list, &iobuf_pool->filled[index]);
}
-out:
return iobuf;
}
@@ -579,6 +546,7 @@ iobuf_get2(struct iobuf_pool *iobuf_pool, size_t page_size)
struct iobuf *iobuf = NULL;
struct iobuf_arena *iobuf_arena = NULL;
size_t rounded_size = 0;
+ int index = 0;
if (page_size == 0) {
page_size = iobuf_pool->default_page_size;
@@ -600,14 +568,23 @@ iobuf_get2(struct iobuf_pool *iobuf_pool, size_t page_size)
return iobuf;
}
+ index = gf_iobuf_get_arena_index(page_size);
+ if (index == -1) {
+ gf_msg("iobuf", GF_LOG_ERROR, 0, LG_MSG_PAGE_SIZE_EXCEEDED,
+ "page_size (%zu) of iobufs in arena being added is "
+ "greater than max available",
+ page_size);
+ return NULL;
+ }
+
pthread_mutex_lock(&iobuf_pool->mutex);
{
/* most eligible arena for picking an iobuf */
- iobuf_arena = __iobuf_select_arena(iobuf_pool, rounded_size);
+ iobuf_arena = __iobuf_select_arena(iobuf_pool, rounded_size, index);
if (!iobuf_arena)
goto unlock;
- iobuf = __iobuf_get(iobuf_arena, rounded_size);
+ iobuf = __iobuf_get(iobuf_arena, rounded_size, index);
if (!iobuf)
goto unlock;
@@ -656,21 +633,31 @@ iobuf_get(struct iobuf_pool *iobuf_pool)
{
struct iobuf *iobuf = NULL;
struct iobuf_arena *iobuf_arena = NULL;
+ int index = 0;
GF_VALIDATE_OR_GOTO("iobuf", iobuf_pool, out);
+ index = gf_iobuf_get_arena_index(iobuf_pool->default_page_size);
+ if (index == -1) {
+ gf_msg("iobuf", GF_LOG_ERROR, 0, LG_MSG_PAGE_SIZE_EXCEEDED,
+ "page_size (%zu) of iobufs in arena being added is "
+ "greater than max available",
+ iobuf_pool->default_page_size);
+ return NULL;
+ }
+
pthread_mutex_lock(&iobuf_pool->mutex);
{
/* most eligible arena for picking an iobuf */
- iobuf_arena = __iobuf_select_arena(iobuf_pool,
- iobuf_pool->default_page_size);
+ iobuf_arena = __iobuf_select_arena(
+ iobuf_pool, iobuf_pool->default_page_size, index);
if (!iobuf_arena) {
gf_msg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_ARENA_NOT_FOUND,
"arena not found");
goto unlock;
}
- iobuf = __iobuf_get(iobuf_arena, iobuf_pool->default_page_size);
+ iobuf = __iobuf_get(iobuf_arena, iobuf_pool->default_page_size, index);
if (!iobuf) {
gf_msg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_IOBUF_NOT_FOUND,
"iobuf not found");
@@ -730,6 +717,7 @@ __iobuf_put(struct iobuf *iobuf, struct iobuf_arena *iobuf_arena)
if (iobuf_arena->active_cnt == 0) {
list_del(&iobuf_arena->list);
list_add_tail(&iobuf_arena->list, &iobuf_pool->purge[index]);
+ GF_VALIDATE_OR_GOTO("iobuf", iobuf_pool, out);
__iobuf_arena_prune(iobuf_pool, iobuf_arena, index);
}
out: