Issue 8347 - lmdb VL32 sometimes not unmapping pages
Summary: lmdb VL32 sometimes not unmapping pages
Status: RESOLVED TEST
Alias: None
Product: LMDB
Classification: Unclassified
Component: liblmdb (show other issues)
Version: unspecified
Hardware: All All
: --- development
Target Milestone: 1.0.0
Assignee: OpenLDAP project
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2016-01-11 17:46 UTC by jeremiah.morrill@econnect.tv
Modified: 2020-03-16 22:50 UTC (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description jeremiah.morrill@econnect.tv 2016-01-11 17:46:16 UTC
Full_Name: Jeremiah Morrill
Version: lmdb 0.9.70
OS: Windows
URL: ftp://ftp.openldap.org/incoming/
Submission from: (NULL) (24.120.130.199)


I changed the value of MDB_ERPAGE_SIZE to 256(16384/64) to try and tweak high
virtual-memory usage in 32bit.  I believe this exposed a bug not hit in my
testing.  Sometimes mmap'd sections(usually one or two) were not being munmapped
when the environment was closed.  This was only evident after checking the
process with the Windows utility VMMap.

I observed that when this happened, in mdb_env_close0, the dangling mmap'd
sections were always at env->me_rpages[(MDB_ERPAGE_SIZE - 1) / 2], which in the
case of MDB_ERPAGE_SIZE of 256, would be at index 127.

This seemed like a possible off-by-one error.  Below is a diff that seems to fix
the issue, but I do not stand by its correctness.

--- a/src/libraries/lmdb/mdb.c
+++ b/src/libraeses/lmdb/mdb.c
@@ -1404,7 +1404,7 @@ struct MDB_env {
 #ifdef MDB_VL32
 	MDB_ID3L	me_rpages;	/**< like #mt_rpages, but global to env */
 	pthread_mutex_t	me_rpmutex;	/**< control access to #me_rpages */
-#define MDB_ERPAGE_SIZE	16384
+#define MDB_ERPAGE_SIZE	(16384/64)
 #define MDB_ERPAGE_MAX	(MDB_ERPAGE_SIZE-1)
 	unsigned int me_rpcheck;
 #endif
@@ -5851,7 +5851,7 @@ retry:
 		if (el[0].mid >= MDB_ERPAGE_MAX - env->me_rpcheck) {
 			/* purge unref'd pages */
 			unsigned i, y = 0;D%D
-			for (i=1; i<el[0].mid; i++) {
+			for (i=1; i<=el[0].mid; i++) {
 				if (!el[i].mref) {
 					if (!y) y = i;
 					munmap(el[i].mptr, env->me_psize * el[i].mcnt);
Comment 1 OpenLDAP project 2016-01-11 20:31:54 UTC
fixed in mdb.master
Comment 2 Howard Chu 2016-01-11 20:31:54 UTC
changed notes
changed state Open to Test
moved from Incoming to Development