Module Name:    src
Committed By:   tsutsui
Date:           Sun Jan 17 04:35:42 UTC 2016

Modified Files:
        src/sys/lib/libsa: cread.c

Log Message:
Add an option (LIBSA_CREAD_NOCRC) to disable gunzip CRC32 calculation.

No obvious sideeffect on booting i386 GENERIC kernels (without the option).
Closes PR/50638 (Extreme slowness on loading gzipped kernels on old CPUs).


To generate a diff of this commit:
cvs rdiff -u -r1.27 -r1.28 src/sys/lib/libsa/cread.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/lib/libsa/cread.c
diff -u src/sys/lib/libsa/cread.c:1.27 src/sys/lib/libsa/cread.c:1.28
--- src/sys/lib/libsa/cread.c:1.27	Sat Jul 25 07:06:11 2015
+++ src/sys/lib/libsa/cread.c	Sun Jan 17 04:35:42 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: cread.c,v 1.27 2015/07/25 07:06:11 isaki Exp $	*/
+/*	$NetBSD: cread.c,v 1.28 2016/01/17 04:35:42 tsutsui Exp $	*/
 
 /*
  * Copyright (c) 1996
@@ -87,10 +87,9 @@ void	zcfree(void *, void *);
 void	zmemcpy(unsigned char *, unsigned char *, unsigned int);
 
 /*
- * The libkern version of this function uses an 8K set of tables.
  * This is the double-loop version of LE CRC32 from if_ethersubr,
- * lightly modified -- it is 200 bytes smaller than the version using
- * a 4-bit table and at least 8K smaller than the libkern version.
+ * lightly modified -- it is ~1KB smaller than libkern version with
+ * DYNAMIC_CRC_TABLE but too much slower especially on ancient poor CPUs.
  */
 #ifndef ETHER_CRC_POLY_LE
 #define ETHER_CRC_POLY_LE	0xedb88320
@@ -98,6 +97,10 @@ void	zmemcpy(unsigned char *, unsigned c
 uint32_t
 crc32(uint32_t crc, const uint8_t *const buf, size_t len)
 {
+#if defined(LIBSA_CREAD_NOCRC)
+	/* XXX provide a stub to avoid pulling a larger libkern version */
+	return crc;
+#else
 	uint32_t c, carry;
 	size_t i, j;
 
@@ -114,6 +117,7 @@ crc32(uint32_t crc, const uint8_t *const
 		}
 	}
 	return (crc ^ 0xffffffffU);
+#endif /* defined(LIBSA_CREAD_NOCRC) */
 }
 
 /*
@@ -317,7 +321,9 @@ ssize_t
 read(int fd, void *buf, size_t len)
 {
 	struct sd *s;
+#if !defined(LIBSA_CREAD_NOCRC)
 	unsigned char *start = buf; /* starting point for crc computation */
+#endif
 
 	s = ss[fd];
 
@@ -373,13 +379,24 @@ read(int fd, void *buf, size_t len)
 		s->z_err = inflate(&(s->stream), Z_NO_FLUSH);
 
 		if (s->z_err == Z_STREAM_END) {
+			uint32_t total_out;
+#if !defined(LIBSA_CREAD_NOCRC)
+			uint32_t crc;
 			/* Check CRC and original size */
 			s->crc = crc32(s->crc, start, (unsigned int)
 					(s->stream.next_out - start));
 			start = s->stream.next_out;
+			crc = getLong(s);
+#else
+			(void)getLong(s);
+#endif
+			total_out = getLong(s);
 
-			if (getLong(s) != s->crc ||
-			    getLong(s) != s->stream.total_out) {
+			if (
+#if !defined(LIBSA_CREAD_NOCRC)
+			    crc != s->crc ||
+#endif
+			    total_out != s->stream.total_out) {
 
 				s->z_err = Z_DATA_ERROR;
 			} else {
@@ -387,7 +404,9 @@ read(int fd, void *buf, size_t len)
 				check_header(s);
 				if (s->z_err == Z_OK) {
 					inflateReset(&(s->stream));
+#if !defined(LIBSA_CREAD_NOCRC)
 					s->crc = crc32(0L, Z_NULL, 0);
+#endif
 				}
 			}
 		}
@@ -395,8 +414,10 @@ read(int fd, void *buf, size_t len)
 			break;
 	}
 
+#if !defined(LIBSA_CREAD_NOCRC)
 	s->crc = crc32(s->crc, start,
 	               (unsigned int)(s->stream.next_out - start));
+#endif
 
 	return (int)(len - s->stream.avail_out);
 }

Reply via email to