1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-10-23 23:33:15 +03:00

Fix all segments memory is allocated from vg private mempool.

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).
This commit is contained in:
Milan Broz
2010-03-31 17:23:18 +00:00
parent 0423887528
commit 6733116a19
6 changed files with 19 additions and 14 deletions

View File

@@ -1,5 +1,6 @@
Version 2.02.63 -
================================
Allocate all segments memory from vg private mempool.
Return newly allocated PV segment after segment split.
Optimise PV segments search for the most last segment search case.
Remove vg_validate call when parsing cached metadata.

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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 **pvseg_allocated);
int release_pv_segment(struct pv_segment *peg, uint32_t area_reduction);
int check_pv_segments(struct volume_group *vg);

View File

@@ -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 not allocated to a LV and returned.
*/
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 **pvseg_allocated)
{
struct pv_segment *pvseg, *pvseg_new = NULL;
@@ -142,7 +144,7 @@ int pv_split_segment(struct physical_volume *pv, uint32_t pe,
goto out;
}
if (!(pvseg_new = _pv_split_segment(pv, pvseg, pe)))
if (!(pvseg_new = _pv_split_segment(mem, pv, pvseg, pe)))
return_0;
out:
if (pvseg_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) {