[lvm-devel] [PATCH 5/5] Fix all segments memory is allocated from vg private mempool.
Milan Broz
mbroz at redhat.com
Mon Mar 29 13:12:58 UTC 2010
Physical segments were still allocated from global
command context mempool.
This leads to very high memory usage when
activating large VG (vgchange).
(Memory usage was about 2G when >3000LVs).
Fix it by properly using vg->vgmem private pool,
so all the memory is released early.
New memory pool parameter is needed here for pv_split_segment
function.
Also fix the same problem in some minor allocations
(vg description, lv segment split).
Signed-off-by: Milan Broz <mbroz at redhat.com>
---
lib/format_text/import.c | 2 +-
lib/metadata/lv_manip.c | 2 +-
lib/metadata/merge.c | 4 ++--
lib/metadata/pv_alloc.h | 3 ++-
lib/metadata/pv_manip.c | 21 ++++++++++++---------
5 files changed, 18 insertions(+), 14 deletions(-)
diff --git a/lib/format_text/import.c b/lib/format_text/import.c
index 03ff990..f686418 100644
--- a/lib/format_text/import.c
+++ b/lib/format_text/import.c
@@ -114,7 +114,7 @@ struct volume_group *text_vg_import_fd(struct format_instance *fid,
if (!(vg = (*vsn)->read_vg(fid, cft, 0)))
goto_out;
- (*vsn)->read_desc(fid->fmt->cmd->mem, cft, when, desc);
+ (*vsn)->read_desc(vg->vgmem, cft, when, desc);
break;
}
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index c9d1759..650bc83 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -47,7 +47,7 @@ int add_seg_to_segs_using_this_lv(struct logical_volume *lv,
log_very_verbose("Adding %s:%" PRIu32 " as an user of %s",
seg->lv->name, seg->le, lv->name);
- if (!(sl = dm_pool_zalloc(lv->vg->cmd->mem, sizeof(*sl)))) {
+ if (!(sl = dm_pool_zalloc(lv->vg->vgmem, sizeof(*sl)))) {
log_error("Failed to allocate segment list");
return 0;
}
diff --git a/lib/metadata/merge.c b/lib/metadata/merge.c
index 66e9ce0..bd65c69 100644
--- a/lib/metadata/merge.c
+++ b/lib/metadata/merge.c
@@ -268,7 +268,7 @@ static int _lv_split_segment(struct logical_volume *lv, struct lv_segment *seg,
}
/* Clone the existing segment */
- if (!(split_seg = alloc_lv_segment(lv->vg->cmd->mem, seg->segtype,
+ if (!(split_seg = alloc_lv_segment(lv->vg->vgmem, seg->segtype,
seg->lv, seg->le, seg->len,
seg->status, seg->stripe_size,
seg->log_lv,
@@ -279,7 +279,7 @@ static int _lv_split_segment(struct logical_volume *lv, struct lv_segment *seg,
return 0;
}
- if (!str_list_dup(lv->vg->cmd->mem, &split_seg->tags, &seg->tags)) {
+ if (!str_list_dup(lv->vg->vgmem, &split_seg->tags, &seg->tags)) {
log_error("LV segment tags duplication failed");
return 0;
}
diff --git a/lib/metadata/pv_alloc.h b/lib/metadata/pv_alloc.h
index 601bbf1..ebf6561 100644
--- a/lib/metadata/pv_alloc.h
+++ b/lib/metadata/pv_alloc.h
@@ -20,7 +20,8 @@ struct pv_segment *assign_peg_to_lvseg(struct physical_volume *pv, uint32_t pe,
uint32_t area_len,
struct lv_segment *seg,
uint32_t area_num);
-int pv_split_segment(struct physical_volume *pv, uint32_t pe,
+int pv_split_segment(struct dm_pool *mem,
+ struct physical_volume *pv, uint32_t pe,
struct pv_segment **peg_allocated);
int release_pv_segment(struct pv_segment *peg, uint32_t area_reduction);
int check_pv_segments(struct volume_group *vg);
diff --git a/lib/metadata/pv_manip.c b/lib/metadata/pv_manip.c
index bd3f488..a4ca7a1 100644
--- a/lib/metadata/pv_manip.c
+++ b/lib/metadata/pv_manip.c
@@ -96,13 +96,14 @@ static struct pv_segment *find_peg_by_pe(const struct physical_volume *pv,
* Split peg at given extent.
* Second part is always deallocated.
*/
-static struct pv_segment *_pv_split_segment(struct physical_volume *pv,
+static struct pv_segment *_pv_split_segment(struct dm_pool *mem,
+ struct physical_volume *pv,
struct pv_segment *peg,
uint32_t pe)
{
struct pv_segment *peg_new;
- if (!(peg_new = _alloc_pv_segment(pv->fmt->cmd->mem, peg->pv, pe,
+ if (!(peg_new = _alloc_pv_segment(mem, peg->pv, pe,
peg->len + peg->pe - pe,
NULL, 0)))
return_NULL;
@@ -122,7 +123,8 @@ static struct pv_segment *_pv_split_segment(struct physical_volume *pv,
/*
* Ensure there is a PV segment boundary at the given extent.
*/
-int pv_split_segment(struct physical_volume *pv, uint32_t pe,
+int pv_split_segment(struct dm_pool *mem,
+ struct physical_volume *pv, uint32_t pe,
struct pv_segment **peg_allocated)
{
struct pv_segment *peg, *peg_new = NULL;
@@ -142,7 +144,7 @@ int pv_split_segment(struct physical_volume *pv, uint32_t pe,
goto out;
}
- if (!(peg_new = _pv_split_segment(pv, peg, pe)))
+ if (!(peg_new = _pv_split_segment(mem, pv, peg, pe)))
return_0;
out:
if (peg_allocated)
@@ -167,8 +169,8 @@ struct pv_segment *assign_peg_to_lvseg(struct physical_volume *pv,
if (!pv)
return &null_pv_segment;
- if (!pv_split_segment(pv, pe, &peg) ||
- !pv_split_segment(pv, pe + area_len, NULL))
+ if (!pv_split_segment(seg->lv->vg->vgmem, pv, pe, &peg) ||
+ !pv_split_segment(seg->lv->vg->vgmem, pv, pe + area_len, NULL))
return_NULL;
if (!peg) {
@@ -206,8 +208,9 @@ int release_pv_segment(struct pv_segment *peg, uint32_t area_reduction)
return 1;
}
- if (!pv_split_segment(peg->pv, peg->pe + peg->lvseg->area_len -
- area_reduction, NULL))
+ if (!pv_split_segment(peg->lvseg->lv->vg->vgmem,
+ peg->pv, peg->pe + peg->lvseg->area_len -
+ area_reduction, NULL))
return_0;
return 1;
@@ -380,7 +383,7 @@ static int _reduce_pv(struct physical_volume *pv, struct volume_group *vg, uint3
}
}
- if (!pv_split_segment(pv, new_pe_count, NULL))
+ if (!pv_split_segment(vg->vgmem, pv, new_pe_count, NULL))
return_0;
dm_list_iterate_items_safe(peg, pegt, &pv->segments) {
--
1.7.0.3
More information about the lvm-devel
mailing list