dm io: use fixed initial mempool size
Replace the arbitrary calculation of an initial io struct mempool size with a constant. The code calculated the number of reserved structures based on the request size and used a "magic" multiplication constant of 4. This patch changes it to reserve a fixed number - itself still chosen quite arbitrarily. Further testing might show if there is a better number to choose. Note that if there is no memory pressure, we can still allocate an arbitrary number of "struct io" structures. One structure is enough to process the whole request. Signed-off-by: Mikulas Patocka <mpatocka@redhat.com> Signed-off-by: Alasdair G Kergon <agk@redhat.com>
This commit is contained in:
parent
d04714580f
commit
bda8efec5c
|
@ -19,6 +19,8 @@
|
||||||
#define DM_MSG_PREFIX "io"
|
#define DM_MSG_PREFIX "io"
|
||||||
|
|
||||||
#define DM_IO_MAX_REGIONS BITS_PER_LONG
|
#define DM_IO_MAX_REGIONS BITS_PER_LONG
|
||||||
|
#define MIN_IOS 16
|
||||||
|
#define MIN_BIOS 16
|
||||||
|
|
||||||
struct dm_io_client {
|
struct dm_io_client {
|
||||||
mempool_t *pool;
|
mempool_t *pool;
|
||||||
|
@ -40,34 +42,22 @@ struct io {
|
||||||
|
|
||||||
static struct kmem_cache *_dm_io_cache;
|
static struct kmem_cache *_dm_io_cache;
|
||||||
|
|
||||||
/*
|
|
||||||
* io contexts are only dynamically allocated for asynchronous
|
|
||||||
* io. Since async io is likely to be the majority of io we'll
|
|
||||||
* have the same number of io contexts as bios! (FIXME: must reduce this).
|
|
||||||
*/
|
|
||||||
|
|
||||||
static unsigned int pages_to_ios(unsigned int pages)
|
|
||||||
{
|
|
||||||
return 4 * pages; /* too many ? */
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create a client with mempool and bioset.
|
* Create a client with mempool and bioset.
|
||||||
*/
|
*/
|
||||||
struct dm_io_client *dm_io_client_create(unsigned num_pages)
|
struct dm_io_client *dm_io_client_create(void)
|
||||||
{
|
{
|
||||||
unsigned ios = pages_to_ios(num_pages);
|
|
||||||
struct dm_io_client *client;
|
struct dm_io_client *client;
|
||||||
|
|
||||||
client = kmalloc(sizeof(*client), GFP_KERNEL);
|
client = kmalloc(sizeof(*client), GFP_KERNEL);
|
||||||
if (!client)
|
if (!client)
|
||||||
return ERR_PTR(-ENOMEM);
|
return ERR_PTR(-ENOMEM);
|
||||||
|
|
||||||
client->pool = mempool_create_slab_pool(ios, _dm_io_cache);
|
client->pool = mempool_create_slab_pool(MIN_IOS, _dm_io_cache);
|
||||||
if (!client->pool)
|
if (!client->pool)
|
||||||
goto bad;
|
goto bad;
|
||||||
|
|
||||||
client->bios = bioset_create(16, 0);
|
client->bios = bioset_create(MIN_BIOS, 0);
|
||||||
if (!client->bios)
|
if (!client->bios)
|
||||||
goto bad;
|
goto bad;
|
||||||
|
|
||||||
|
@ -81,13 +71,6 @@ struct dm_io_client *dm_io_client_create(unsigned num_pages)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(dm_io_client_create);
|
EXPORT_SYMBOL(dm_io_client_create);
|
||||||
|
|
||||||
int dm_io_client_resize(unsigned num_pages, struct dm_io_client *client)
|
|
||||||
{
|
|
||||||
return mempool_resize(client->pool, pages_to_ios(num_pages),
|
|
||||||
GFP_KERNEL);
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(dm_io_client_resize);
|
|
||||||
|
|
||||||
void dm_io_client_destroy(struct dm_io_client *client)
|
void dm_io_client_destroy(struct dm_io_client *client)
|
||||||
{
|
{
|
||||||
mempool_destroy(client->pool);
|
mempool_destroy(client->pool);
|
||||||
|
|
|
@ -667,7 +667,7 @@ int dm_kcopyd_client_create(unsigned min_pages,
|
||||||
if (r)
|
if (r)
|
||||||
goto bad_client_pages;
|
goto bad_client_pages;
|
||||||
|
|
||||||
kc->io_client = dm_io_client_create(min_pages);
|
kc->io_client = dm_io_client_create();
|
||||||
if (IS_ERR(kc->io_client)) {
|
if (IS_ERR(kc->io_client)) {
|
||||||
r = PTR_ERR(kc->io_client);
|
r = PTR_ERR(kc->io_client);
|
||||||
goto bad_io_client;
|
goto bad_io_client;
|
||||||
|
|
|
@ -449,8 +449,7 @@ static int create_log_context(struct dm_dirty_log *log, struct dm_target *ti,
|
||||||
|
|
||||||
lc->io_req.mem.type = DM_IO_VMA;
|
lc->io_req.mem.type = DM_IO_VMA;
|
||||||
lc->io_req.notify.fn = NULL;
|
lc->io_req.notify.fn = NULL;
|
||||||
lc->io_req.client = dm_io_client_create(dm_div_up(buf_size,
|
lc->io_req.client = dm_io_client_create();
|
||||||
PAGE_SIZE));
|
|
||||||
if (IS_ERR(lc->io_req.client)) {
|
if (IS_ERR(lc->io_req.client)) {
|
||||||
r = PTR_ERR(lc->io_req.client);
|
r = PTR_ERR(lc->io_req.client);
|
||||||
DMWARN("couldn't allocate disk io client");
|
DMWARN("couldn't allocate disk io client");
|
||||||
|
|
|
@ -22,7 +22,6 @@
|
||||||
#define DM_MSG_PREFIX "raid1"
|
#define DM_MSG_PREFIX "raid1"
|
||||||
|
|
||||||
#define MAX_RECOVERY 1 /* Maximum number of regions recovered in parallel. */
|
#define MAX_RECOVERY 1 /* Maximum number of regions recovered in parallel. */
|
||||||
#define DM_IO_PAGES 64
|
|
||||||
#define DM_KCOPYD_PAGES 64
|
#define DM_KCOPYD_PAGES 64
|
||||||
|
|
||||||
#define DM_RAID1_HANDLE_ERRORS 0x01
|
#define DM_RAID1_HANDLE_ERRORS 0x01
|
||||||
|
@ -887,7 +886,7 @@ static struct mirror_set *alloc_context(unsigned int nr_mirrors,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ms->io_client = dm_io_client_create(DM_IO_PAGES);
|
ms->io_client = dm_io_client_create();
|
||||||
if (IS_ERR(ms->io_client)) {
|
if (IS_ERR(ms->io_client)) {
|
||||||
ti->error = "Error creating dm_io client";
|
ti->error = "Error creating dm_io client";
|
||||||
mempool_destroy(ms->read_record_pool);
|
mempool_destroy(ms->read_record_pool);
|
||||||
|
|
|
@ -154,11 +154,6 @@ struct pstore {
|
||||||
struct workqueue_struct *metadata_wq;
|
struct workqueue_struct *metadata_wq;
|
||||||
};
|
};
|
||||||
|
|
||||||
static unsigned sectors_to_pages(unsigned sectors)
|
|
||||||
{
|
|
||||||
return DIV_ROUND_UP(sectors, PAGE_SIZE >> 9);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int alloc_area(struct pstore *ps)
|
static int alloc_area(struct pstore *ps)
|
||||||
{
|
{
|
||||||
int r = -ENOMEM;
|
int r = -ENOMEM;
|
||||||
|
@ -318,8 +313,7 @@ static int read_header(struct pstore *ps, int *new_snapshot)
|
||||||
chunk_size_supplied = 0;
|
chunk_size_supplied = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ps->io_client = dm_io_client_create(sectors_to_pages(ps->store->
|
ps->io_client = dm_io_client_create();
|
||||||
chunk_size));
|
|
||||||
if (IS_ERR(ps->io_client))
|
if (IS_ERR(ps->io_client))
|
||||||
return PTR_ERR(ps->io_client);
|
return PTR_ERR(ps->io_client);
|
||||||
|
|
||||||
|
@ -368,11 +362,6 @@ static int read_header(struct pstore *ps, int *new_snapshot)
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = dm_io_client_resize(sectors_to_pages(ps->store->chunk_size),
|
|
||||||
ps->io_client);
|
|
||||||
if (r)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
r = alloc_area(ps);
|
r = alloc_area(ps);
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
|
|
@ -69,8 +69,7 @@ struct dm_io_request {
|
||||||
*
|
*
|
||||||
* Create/destroy may block.
|
* Create/destroy may block.
|
||||||
*/
|
*/
|
||||||
struct dm_io_client *dm_io_client_create(unsigned num_pages);
|
struct dm_io_client *dm_io_client_create(void);
|
||||||
int dm_io_client_resize(unsigned num_pages, struct dm_io_client *client);
|
|
||||||
void dm_io_client_destroy(struct dm_io_client *client);
|
void dm_io_client_destroy(struct dm_io_client *client);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in New Issue