]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
common/crc32c_intel_fast: avoid reading partial trailing word
authorSage Weil <sage@inktank.com>
Thu, 5 Sep 2013 04:29:11 +0000 (21:29 -0700)
committerSage Weil <sage@inktank.com>
Fri, 6 Sep 2013 16:31:59 +0000 (09:31 -0700)
The optimized intel code reads in word-sized chunks, knowing that the
allocator will only hand out memory in word-sized increments.   This makes
valgrind unhappy.  Whitelisting doesn't work because for some reason there
is no caller context (probably because of some interaction with yasm?).

Instead, just use the baseline code for the last few bytes.  This should
not be significant.

Signed-off-by: Sage Weil <sage@inktank.com>
Reviewed-by: Greg Farnum <greg@inktank.com>
src/common/crc32c_intel_fast.c
src/test/common/test_crc32c.cc

index b446fc1ecc5eddb4b8661a33fcb275380d225367..49305088affee8382109d9232db7d83dec51e9be 100644 (file)
@@ -1,5 +1,6 @@
 #include <inttypes.h>
 #include "acconfig.h"
+#include "common/crc32c_intel_baseline.h"
 
 extern unsigned int crc32_iscsi_00(unsigned char const *buffer, int len, unsigned int crc);
 
@@ -7,7 +8,22 @@ extern unsigned int crc32_iscsi_00(unsigned char const *buffer, int len, unsigne
 
 uint32_t ceph_crc32c_intel_fast(uint32_t crc, unsigned char const *buffer, unsigned len)
 {
-       return crc32_iscsi_00(buffer, len, crc);
+       uint32_t v;
+       unsigned left;
+
+       /*
+        * the crc32_iscsi_00 method reads past buffer+len (because it
+        * reads full words) which makes valgrind unhappy.  don't do
+        * that.
+        */
+       if (len < 16)
+               return ceph_crc32c_intel_baseline(crc, buffer, len);
+       left = ((unsigned long)buffer + len) & 7;
+       len -= left;
+       v = crc32_iscsi_00(buffer, len, crc);
+       if (left)
+               v = ceph_crc32c_intel_baseline(v, buffer + len, left);
+       return v;
 }
 
 int ceph_crc32c_intel_fast_exists(void)
index 19a1dfb72842056a8936f4dd09a5c3f3248ca109..5cf88de0a8006ff8e78e668883c65a504acce552 100644 (file)
@@ -23,6 +23,15 @@ TEST(Crc32c, Small) {
   ASSERT_EQ(3743019208u, ceph_crc32c(5678, (unsigned char *)b, strlen(b)));
 }
 
+TEST(Crc32c, PartialWord) {
+  const char *a = (const char *)malloc(5);
+  const char *b = (const char *)malloc(35);
+  memset((void *)a, 1, 5);
+  memset((void *)b, 1, 35);
+  ASSERT_EQ(2715569182u, ceph_crc32c(0, (unsigned char *)a, 5));
+  ASSERT_EQ(440531800u, ceph_crc32c(0, (unsigned char *)b, 35));
+}
+
 TEST(Crc32c, Big) {
   int len = 4096000;
   char *a = (char *)malloc(len);