On Sat, Dec 20, 2008 at 11:28 PM, Nitin Gupta <[email protected]> wrote:
>> Are either of these "issues"? I could probably whip up a patch in the
>> time it would take me to submit an issue.
>
>
> Patch would be nice! :)

I have attached a patch for you to look at. It isn't ready to be
applied, but I have some questions.

1) Using Kmalloc instead of xv if size > PAGE_SIZE-512

This is against compcache.c. Currently it does not even try to support
64bit or kfree on unload. Also for some reason it crashes after
writing "setting size to ..." to /var/log/syslog.

However does this seem a worthwhile approach?

2) warning the user if size is too large.

In this patch I have used both "cat <<EOF" and multi line echo. I
should probably pick just one. Do you have a preference?

-- 
John C. McCabe-Dansted
PhD Student
University of Western Australia
Index: compcache.c
===================================================================
--- compcache.c	(revision 243)
+++ compcache.c	(working copy)
@@ -115,6 +115,7 @@
 	size_t clen, page_no;
 	void *user_mem, *cmem;
 	struct page *page;
+	int alloc_error;
 
 	if (!valid_swap_request(bio)) {
 		stat_inc(stats.invalid_io);
@@ -148,24 +149,28 @@
 
 
 		clen = PAGE_SIZE;
-		cmem = (char *)xvMapPage(compcache.table[page_no].pageNum) +
-				compcache.table[page_no].offset;
 
 		/* Page is stored uncompressed since its incompressible */
 		if (unlikely(compcache.table[page_no].len == PAGE_SIZE)) {
+			cmem = (char *) compcache.table[page_no].pageNum;
 			memcpy(user_mem, cmem, PAGE_SIZE);
 			kunmap(page);
-			xvUnmapPage(compcache.table[page_no].pageNum);
+			/*xvUnmapPage(compcache.table[page_no].pageNum);*/
 			set_bit(BIO_UPTODATE, &bio->bi_flags);
 			BIO_ENDIO(bio, 0);
 			return 0;
+		} else {
+			cmem = (char *)xvMapPage(compcache.table[page_no].pageNum) +
+				compcache.table[page_no].offset;
 		}
 
 		ret = lzo1x_decompress_safe(
 			cmem, compcache.table[page_no].len,
 			user_mem, &clen);
 
-		xvUnmapPage(compcache.table[page_no].pageNum);
+		if (compcache.table[page_no].len != PAGE_SIZE) {
+			xvUnmapPage(compcache.table[page_no].pageNum);
+		}
 
 		/* should NEVER happen */
 		if (unlikely(ret != LZO_E_OK)) {
@@ -189,9 +194,13 @@
 		 * to free the memory that was allocated for this page.
 		 */
 		if (compcache.table[page_no].pageNum) {
-			xvFree(compcache.mem_pool,
-				compcache.table[page_no].pageNum,
-				compcache.table[page_no].offset);
+			if (compcache.table[page_no].len==PAGE_SIZE) {
+				kfree((char*)compcache.table[page_no].pageNum);
+			} else {
+				xvFree(compcache.mem_pool,
+					compcache.table[page_no].pageNum,
+					compcache.table[page_no].offset);
+			}
 			stat_dec(stats.curr_pages);
 			stat_set(stats.curr_mem, stats.curr_mem	-
 					compcache.table[page_no].len);
@@ -212,15 +221,28 @@
 			goto out;
 		}
 
+		alloc_error=0;
+
 		/* Page is incompressible - store it as is */
-		if (clen >= PAGE_SIZE) {
+		/*if (clen >= PAGE_SIZE) {*/
+		if (unlikely(clen > (PAGE_SIZE-512))){
 			clen = PAGE_SIZE;
 			src = user_mem;
+			if (!(cmem=kmalloc(PAGE_SIZE,GFP_KERNEL))) {
+				alloc_error=1;
+			}
+			compcache.table[page_no].pageNum=(u32)(cmem);
+		} else {
+			if (unlikely(xvMalloc(compcache.mem_pool, clen,
+				&compcache.table[page_no].pageNum,
+				&offset))) {
+			alloc_error=2;
+			} else { 
+				cmem = (char *)xvMapPage(compcache.table[page_no].pageNum) + compcache.table[page_no].offset;
+			}
 		}
 
-		if (xvMalloc(compcache.mem_pool, clen,
-				&compcache.table[page_no].pageNum,
-				&offset)) {
+		if (alloc_error) {
 			mutex_unlock(&compcache.lock);
 #if defined(VERBOSE)
 			pr_info(C "Error allocating memory for compressed "
@@ -235,12 +257,10 @@
 
 		compcache.table[page_no].offset = offset;
 		
-		cmem = (char *)xvMapPage(compcache.table[page_no].pageNum) +
-				compcache.table[page_no].offset;
-
 		memcpy(cmem, src, clen);
 
-		xvUnmapPage(compcache.table[page_no].pageNum);
+		if (clen!=PAGE_SIZE) 
+			xvUnmapPage(compcache.table[page_no].pageNum);
 
 		/* Update stats */
 		stat_inc(stats.curr_pages);
Index: use_compcache.sh
===================================================================
--- use_compcache.sh	(revision 243)
+++ use_compcache.sh	(working copy)
@@ -9,7 +9,6 @@
 
 MOD_PARAM=""
 SIZE_KB="$1"
-SIZE_KB="$1"
 
 LSMOD_BIN=/sbin/lsmod
 INSMOD_BIN=/sbin/insmod
@@ -32,6 +31,43 @@
 	fi
 }
 
+if uname -m | grep i[3-7]86 > /dev/null
+then
+	# "32bit kernel"
+	if [ $SIZE_KB -gt 1048576 ]
+	then
+		echo 
+		cat <<EOF
+On i386 based systems the kernel is usually only allowed to allocate up to 1GB, so we do not want compcache to allocate too much of this memory. We recommend that you use a compcache smaller that 1GB so that compcache uses less than about 500MB when the compcache device is full.
+EOF
+		echo
+	fi
+fi
+
+MEM_SIZE_KB=`grep MemTotal: /proc/meminfo  | sed s/[^0-9]//g`
+
+if [ $(($MEM_SIZE_KB*2)) -lt $SIZE_KB ]
+then 
+	echo "There is little point creating a compcache of greater than twice"
+	echo "the size of memory since we expect a 2:1 compression ratio"
+	echo "Note that compcache uses about 0.1% of the size of the swap"
+	echo "device when not in use so a huge compcache is wasteful."
+	echo
+	echo "Memory Size: $MEM_SIZE_KB kB"
+	echo "Size you selected: $SIZE_KB kB"
+	if [ $(($MEM_SIZE_KB*8)) -lt $SIZE_KB ]
+	then
+		echo
+		echo "This is over 8 times the size of memory."
+		echo "You have probably addded too many zeros."
+		echo "aborting."
+	else 
+		echo
+		echo "Loading compcache anyway."
+	fi
+	exit 1
+fi
+
 # Some distos already have LZO de/compress modules
 echo "Loading modules ..."
 $MODPROBE_BIN -q lzo_compress  || INSMOD lzo1x_compress
_______________________________________________
linux-mm-cc mailing list
[email protected]
http://lists.laptop.org/listinfo/linux-mm-cc

Reply via email to