From 450d030a3d195428bf3a736c506285264172e567 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=B6r=C3=B6k=20Edvin?= Date: Mon, 14 Mar 2011 20:29:27 +0200 Subject: [PATCH] fmap: reduce amount of mmap() calls in fmap_aging. Scanning /dev/shm on an old kernel is serialized due to the additional mmap contention that fmap_aging generates. With this change it regains some parallelism (still not optimal), and it also helps on newer kernels (less mmap calls is always good). This patch makes just one mmap call for an entire range of pages, if we try to unmap adjacent pages. --- libclamav/fmap.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/libclamav/fmap.c b/libclamav/fmap.c index 2c964edca..48974667c 100644 --- a/libclamav/fmap.c +++ b/libclamav/fmap.c @@ -189,13 +189,33 @@ static void fmap_aging(fmap_t *m) { } } if(avail) { /* at least one page is paged and not locked */ + char *lastpage = NULL; + char *firstpage = NULL; for(i=0; ipgsz + m->hdrsz; /* we mark the page as seen */ fmap_bitmap[freeme[i]] = FM_MASK_SEEN; /* and we mmap the page over so the kernel knows there's nothing good in there */ + /* reduce number of mmap calls: if pages are adjacent only do 1 mmap call */ + if (lastpage && pptr == lastpage) { + lastpage = pptr + m->pgsz; + continue; + } + if (!lastpage) { + firstpage = pptr; + lastpage = pptr + m->pgsz; + continue; + } + fmap_lock; + if(mmap(firstpage, lastpage - firstpage, PROT_READ | PROT_WRITE, MAP_FIXED|MAP_PRIVATE|ANONYMOUS_MAP, -1, 0) == MAP_FAILED) + cli_dbgmsg("fmap_aging: kernel hates you\n"); + fmap_unlock; + firstpage = pptr; + lastpage = pptr + m->pgsz; + } + if (lastpage) { fmap_lock; - if(mmap(pptr, m->pgsz, PROT_READ | PROT_WRITE, MAP_FIXED|MAP_PRIVATE|ANONYMOUS_MAP, -1, 0) == MAP_FAILED) + if(mmap(firstpage, lastpage - firstpage, PROT_READ | PROT_WRITE, MAP_FIXED|MAP_PRIVATE|ANONYMOUS_MAP, -1, 0) == MAP_FAILED) cli_dbgmsg("fmap_aging: kernel hates you\n"); fmap_unlock; }