diff options
author | Keir Fraser <keir.fraser@citrix.com> | 2009-12-09 10:44:56 +0000 |
---|---|---|
committer | Keir Fraser <keir.fraser@citrix.com> | 2009-12-09 10:44:56 +0000 |
commit | 51010e4de3d40cd83549768c2cf10ecdcf6ee4a8 (patch) | |
tree | ea18e6921dd14d075e32d4b263cb6a16d674203c /xen/common/tmem.c | |
parent | 9905ac2b90a3e7cecd9e7dfe21c252362e7080b2 (diff) | |
download | xen-51010e4de3d40cd83549768c2cf10ecdcf6ee4a8.tar.gz xen-51010e4de3d40cd83549768c2cf10ecdcf6ee4a8.tar.bz2 xen-51010e4de3d40cd83549768c2cf10ecdcf6ee4a8.zip |
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>
Diffstat (limited to 'xen/common/tmem.c')
-rw-r--r-- | xen/common/tmem.c | 20 |
1 files changed, 20 insertions, 0 deletions
diff --git a/xen/common/tmem.c b/xen/common/tmem.c index af1537d3b5..ab1b3cd8f6 100644 --- a/xen/common/tmem.c +++ b/xen/common/tmem.c @@ -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; |