Skip to content
This repository was archived by the owner on Nov 12, 2025. It is now read-only.

Commit 067aa12

Browse files
committed
common: decrease stack usage by Malloc replacement
Use Malloc to allocate big local data structure to avoid stack overusage. Signed-off-by: Tomasz Gromadzki <[email protected]>
1 parent aa42768 commit 067aa12

File tree

3 files changed

+69
-32
lines changed

3 files changed

+69
-32
lines changed

ChangeLog

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
This release:
44
- Significantly reduces the libpmem's stack usage.
5+
- Use Malloc for big local data structure to avoid huge stack usage
6+
57

68
Tue Aug 8 2023 Oksana Sałyk <[email protected]>
79

src/common/mmap_posix.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "mmap.h"
1212
#include "out.h"
1313
#include "os.h"
14+
#include "alloc.h"
1415

1516
#define PROCMAXLEN 2048 /* maximum expected line length in /proc files */
1617

@@ -31,6 +32,8 @@ static const char * const sscanf_os = "%p-%p";
3132
* Asking for aligned address like this will allow the DAX code to use large
3233
* mappings. It is not an error if mmap() ignores the hint and chooses
3334
* different address.
35+
*
36+
* Return MAP_FAILED in case of an error.
3437
*/
3538
char *
3639
util_map_hint_unused(void *minaddr, size_t len, size_t align)
@@ -44,11 +47,18 @@ util_map_hint_unused(void *minaddr, size_t len, size_t align)
4447
return MAP_FAILED;
4548
}
4649

47-
char line[PROCMAXLEN]; /* for fgets() */
50+
char *line = NULL; /* for fgets() */
4851
char *lo = NULL; /* beginning of current range in maps file */
4952
char *hi = NULL; /* end of current range in maps file */
5053
char *raddr = minaddr; /* ignore regions below 'minaddr' */
5154

55+
line = Malloc(PROCMAXLEN);
56+
if (line == NULL) {
57+
ERR("!Malloc");
58+
errno = ENOMEM;
59+
return MAP_FAILED;
60+
}
61+
5262
if (raddr == NULL)
5363
raddr += Pagesize;
5464

@@ -93,6 +103,7 @@ util_map_hint_unused(void *minaddr, size_t len, size_t align)
93103

94104
fclose(fp);
95105

106+
Free(line);
96107
LOG(3, "returning %p", raddr);
97108
return raddr;
98109
}

src/common/set.c

Lines changed: 55 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1791,46 +1791,60 @@ util_header_check(struct pool_set *set, unsigned repidx, unsigned partidx,
17911791

17921792
ASSERTne(attr, NULL);
17931793

1794+
int ret = 0;
1795+
17941796
struct pool_replica *rep = set->replica[repidx];
17951797

17961798
/* opaque info lives at the beginning of mapped memory pool */
17971799
struct pool_hdr *hdrp = rep->part[partidx].hdr;
1798-
struct pool_hdr hdr;
1800+
struct pool_hdr *hdr;
1801+
1802+
hdr = Malloc(sizeof(struct pool_hdr));
1803+
if (hdr == NULL) {
1804+
ERR("!Malloc");
1805+
errno = ENOMEM;
1806+
return -1;
1807+
}
17991808

1800-
memcpy(&hdr, hdrp, sizeof(hdr));
1809+
memcpy(hdr, hdrp, sizeof(*hdr));
18011810

1802-
util_convert2h_hdr_nocheck(&hdr);
1811+
util_convert2h_hdr_nocheck(hdr);
18031812

18041813
/* to be valid, a header must have a major version of at least 1 */
1805-
if (hdr.major == 0) {
1814+
if (hdr->major == 0) {
18061815
ERR("invalid major version (0)");
18071816
errno = EINVAL;
1808-
return -1;
1817+
ret = -1;
1818+
goto end;
18091819
}
18101820

18111821
/* check signature */
1812-
if (memcmp(hdr.signature, attr->signature, POOL_HDR_SIG_LEN)) {
1813-
ERR("wrong pool type: \"%.8s\"", hdr.signature);
1822+
if (memcmp(hdr->signature, attr->signature, POOL_HDR_SIG_LEN)) {
1823+
ERR("wrong pool type: \"%.8s\"", hdr->signature);
18141824
errno = EINVAL;
1815-
return -1;
1825+
ret = -1;
1826+
goto end;
18161827
}
18171828

18181829
/* check format version number */
1819-
if (hdr.major != attr->major) {
1820-
ERR("pool version %d (library expects %d)", hdr.major,
1830+
if (hdr->major != attr->major) {
1831+
ERR("pool version %d (library expects %d)", hdr->major,
18211832
attr->major);
1822-
if (hdr.major < attr->major)
1833+
if (hdr->major < attr->major)
18231834
ERR(
18241835
"Please run the pmdk-convert utility to upgrade the pool.");
18251836
errno = EINVAL;
1826-
return -1;
1837+
ret = -1;
1838+
goto end;
18271839
}
18281840

18291841
rep->part[partidx].rdonly = 0;
18301842

1831-
int retval = util_feature_check(&hdr, attr->features);
1832-
if (retval < 0)
1833-
return -1;
1843+
int retval = util_feature_check(hdr, attr->features);
1844+
if (retval < 0) {
1845+
ret = -1;
1846+
goto end;
1847+
}
18341848

18351849
if (retval == 0)
18361850
rep->part[partidx].rdonly = 1;
@@ -1843,44 +1857,49 @@ util_header_check(struct pool_set *set, unsigned repidx, unsigned partidx,
18431857
* we want to report it as incompatible feature, rather than
18441858
* invalid checksum.
18451859
*/
1846-
if (!util_checksum(&hdr, sizeof(hdr), &hdr.checksum,
1847-
0, POOL_HDR_CSUM_END_OFF(&hdr))) {
1860+
if (!util_checksum(hdr, sizeof(*hdr), &hdr->checksum,
1861+
0, POOL_HDR_CSUM_END_OFF(hdr))) {
18481862
ERR("invalid checksum of pool header");
18491863
errno = EINVAL;
1850-
return -1;
1864+
ret = -1;
1865+
goto end;
18511866
}
18521867

1853-
LOG(3, "valid header, signature \"%.8s\"", hdr.signature);
1868+
LOG(3, "valid header, signature \"%.8s\"", hdr->signature);
18541869

1855-
if (util_check_arch_flags(&hdr.arch_flags)) {
1870+
if (util_check_arch_flags(&hdr->arch_flags)) {
18561871
ERR("wrong architecture flags");
18571872
errno = EINVAL;
1858-
return -1;
1873+
ret = -1;
1874+
goto end;
18591875
}
18601876

18611877
/* check pool set UUID */
1862-
if (memcmp(HDR(REP(set, 0), 0)->poolset_uuid, hdr.poolset_uuid,
1878+
if (memcmp(HDR(REP(set, 0), 0)->poolset_uuid, hdr->poolset_uuid,
18631879
POOL_HDR_UUID_LEN)) {
18641880
ERR("wrong pool set UUID");
18651881
errno = EINVAL;
1866-
return -1;
1882+
ret = -1;
1883+
goto end;
18671884
}
18681885

18691886
/* check pool set linkage */
1870-
if (memcmp(HDRP(rep, partidx)->uuid, hdr.prev_part_uuid,
1887+
if (memcmp(HDRP(rep, partidx)->uuid, hdr->prev_part_uuid,
18711888
POOL_HDR_UUID_LEN) ||
1872-
memcmp(HDRN(rep, partidx)->uuid, hdr.next_part_uuid,
1889+
memcmp(HDRN(rep, partidx)->uuid, hdr->next_part_uuid,
18731890
POOL_HDR_UUID_LEN)) {
18741891
ERR("wrong part UUID");
18751892
errno = EINVAL;
1876-
return -1;
1893+
ret = -1;
1894+
goto end;
18771895
}
18781896

18791897
/* check format version */
18801898
if (HDR(rep, 0)->major != hdrp->major) {
18811899
ERR("incompatible pool format");
18821900
errno = EINVAL;
1883-
return -1;
1901+
ret = -1;
1902+
goto end;
18841903
}
18851904

18861905
/* check compatibility features */
@@ -1889,15 +1908,20 @@ util_header_check(struct pool_set *set, unsigned repidx, unsigned partidx,
18891908
HDR(rep, 0)->features.ro_compat != hdrp->features.ro_compat) {
18901909
ERR("incompatible feature flags");
18911910
errno = EINVAL;
1892-
return -1;
1911+
ret = -1;
1912+
goto end;
18931913
}
18941914

18951915
/* check poolset options */
18961916
if (util_poolset_check_header_options(set,
1897-
HDR(rep, 0)->features.incompat))
1898-
return -1;
1917+
HDR(rep, 0)->features.incompat)) {
1918+
ret = -1;
1919+
goto end;
1920+
}
1921+
end:
1922+
Free(hdr);
18991923

1900-
return 0;
1924+
return ret;
19011925
}
19021926

19031927
/*

0 commit comments

Comments
 (0)