summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSage Weil <sage@inktank.com>2013-09-04 21:29:11 -0700
committerSage Weil <sage@inktank.com>2013-09-27 10:55:41 -0700
commitb06c1898ea6913ae5e1e21fffc4b227a548f9b88 (patch)
tree023e97730479cf1794961c115db8a66e19479827
parent5e3145a4d3ee50be6cb6542d2be192eb60fd6f8e (diff)
downloadceph-b06c1898ea6913ae5e1e21fffc4b227a548f9b88.tar.gz
common/crc32c_intel_fast: avoid reading partial trailing word
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> (cherry picked from commit 39c89dcfed0587f822e2226f2de8e4092449af29) Conflicts: src/test/common/test_crc32c.cc
-rw-r--r--src/common/crc32c_intel_fast.c18
1 files changed, 17 insertions, 1 deletions
diff --git a/src/common/crc32c_intel_fast.c b/src/common/crc32c_intel_fast.c
index b446fc1ecc5..49305088aff 100644
--- a/src/common/crc32c_intel_fast.c
+++ b/src/common/crc32c_intel_fast.c
@@ -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)