tmem: reclaim minimal memory proactively

When a single domain is using most/all of tmem memory
for ephemeral pages belonging to the same object, e.g.
when copying a single huge file larger than ephemeral
memory, long lists are traversed looking for a page to
evict that doesn't belong to this object (as pages in
the object for which a page is currently being inserted
are locked and cannot be evicted).  This is essentially
a livelock.

Avoid this by proactively ensuring there is a margin
of available memory (1MB) before locks are taken on
the object.

Signed-off-by: Dan Magenheimer <dan.magenheimer@oracle.com>
This commit is contained in:
Keir Fraser committed 2009-12-09 10:44:56 +00:00
1 parent 9905ac2b90
commit 51010e4de3
2 files changed
+25

No files matched your search

+20
View File
@@ -1093,6 +1093,24 @@ static unsigned long tmem_relinquish_npages(unsigned long n)
return avail_pages;
}
/* Under certain conditions (e.g. if each client is putting pages for exactly
* one object), once locks are held, freeing up memory may
* result in livelocks and very long "put" times, so we try to ensure there
* is a minimum amount of memory (1MB) available BEFORE any data structure
* locks are held */
static inline void tmem_ensure_avail_pages(void)
{
int failed_evict = 10;
while ( !tmh_free_mb() )
{
if ( tmem_evict() )
continue;
else if ( failed_evict-- <= 0 )
break;
}
}
/************ TMEM CORE OPERATIONS ************************************/
static NOINLINE int do_tmem_put_compress(pgp_t *pgp, tmem_cli_mfn_t cmfn,
@@ -2315,10 +2333,12 @@ EXPORT long do_tmem_op(tmem_cli_op_t uops)
op.u.new.uuid[0], op.u.new.uuid[1]);
break;
case TMEM_NEW_PAGE:
tmem_ensure_avail_pages();
rc = do_tmem_put(pool, op.u.gen.object,
op.u.gen.index, op.u.gen.cmfn, 0, 0, 0, NULL);
break;
case TMEM_PUT_PAGE:
tmem_ensure_avail_pages();
rc = do_tmem_put(pool, op.u.gen.object,
op.u.gen.index, op.u.gen.cmfn, 0, 0, PAGE_SIZE, NULL);
if (rc == 1) succ_put = 1;
+5
View File
@@ -252,6 +252,11 @@ static inline unsigned long tmh_freeable_mb(void)
(20 - PAGE_SHIFT);
}
static inline unsigned long tmh_free_mb(void)
{
return (tmh_avail_pages() + total_free_pages()) >> (20 - PAGE_SHIFT);
}
/*
* Memory allocation for "infrastructure" data
*/
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.