forked from ceph/ceph
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
crc32c: Add crc32c function optimized for ppc architecture
Add a performance optimized crc32c function for ppc64le that uses Altivec assembly instructions. Add an architecture probe for ppc (PowerPC 'ppc64le' architecture). When the architecture probe detects that the ppc specific crc32c function (ceph_crc32c_ppc) can be used, it will do so instead of using the default crc32c function (ceph_crc32c_sctp). Signed-off-by: Andrew Solomon <[email protected]>
- Loading branch information
Showing
11 changed files
with
1,940 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
/* Copyright (C) 2017 International Business Machines Corp. | ||
* All rights reserved. | ||
* | ||
* This program is free software; you can redistribute it and/or | ||
* modify it under the terms of the GNU General Public License | ||
* as published by the Free Software Foundation; either version | ||
* 2 of the License, or (at your option) any later version. | ||
*/ | ||
#include "arch/ppc.h" | ||
#include "arch/probe.h" | ||
|
||
/* flags we export */ | ||
int ceph_arch_ppc_crc32 = 0; | ||
|
||
#include <stdio.h> | ||
#include <sys/auxv.h> | ||
|
||
#if __linux__ && __powerpc64__ | ||
#include <asm/cputable.h> | ||
#endif /* __linux__ && __powerpc64__ */ | ||
|
||
#ifndef PPC_FEATURE2_VEC_CRYPTO | ||
#define PPC_FEATURE2_VEC_CRYPTO 0x02000000 | ||
#endif | ||
|
||
#ifndef AT_HWCAP2 | ||
#define AT_HWCAP2 26 | ||
#endif | ||
|
||
int ceph_arch_ppc_probe(void) | ||
{ | ||
ceph_arch_ppc_crc32 = 0; | ||
|
||
#if __linux__ && __powerpc64__ | ||
if (getauxval(AT_HWCAP2) & PPC_FEATURE2_VEC_CRYPTO) ceph_arch_ppc_crc32 = 1; | ||
#endif /* __linux__ && __powerpc64__ */ | ||
|
||
return 0; | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
/* Copyright (C) 2017 International Business Machines Corp. | ||
* All rights reserved. | ||
* | ||
* This program is free software; you can redistribute it and/or | ||
* modify it under the terms of the GNU General Public License | ||
* as published by the Free Software Foundation; either version | ||
* 2 of the License, or (at your option) any later version. | ||
*/ | ||
#ifndef CEPH_ARCH_PPC_H | ||
#define CEPH_ARCH_PPC_H | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
extern int ceph_arch_ppc_crc32; | ||
|
||
extern int ceph_arch_ppc_probe(void); | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
/* Copyright (C) 2017 International Business Machines Corp. | ||
* All rights reserved. | ||
* | ||
* This program is free software; you can redistribute it and/or | ||
* modify it under the terms of the GNU General Public License | ||
* as published by the Free Software Foundation; either version | ||
* 2 of the License, or (at your option) any later version. | ||
*/ | ||
#define CRC_TABLE | ||
#include "acconfig.h" | ||
#include "include/int_types.h" | ||
#include "crc32c_ppc_constants.h" | ||
|
||
#include <stdlib.h> | ||
#include <strings.h> | ||
|
||
#define VMX_ALIGN 16 | ||
#define VMX_ALIGN_MASK (VMX_ALIGN-1) | ||
|
||
#ifdef REFLECT | ||
static unsigned int crc32_align(unsigned int crc, unsigned char const *p, | ||
unsigned long len) | ||
{ | ||
while (len--) | ||
crc = crc_table[(crc ^ *p++) & 0xff] ^ (crc >> 8); | ||
return crc; | ||
} | ||
#else | ||
static unsigned int crc32_align(unsigned int crc, unsigned char const *p, | ||
unsigned long len) | ||
{ | ||
while (len--) | ||
crc = crc_table[((crc >> 24) ^ *p++) & 0xff] ^ (crc << 8); | ||
return crc; | ||
} | ||
#endif | ||
|
||
|
||
#ifdef HAVE_POWER8 | ||
unsigned int __crc32_vpmsum(unsigned int crc, unsigned char const *p, | ||
unsigned long len); | ||
|
||
static uint32_t crc32_vpmsum(uint32_t crc, unsigned char const *data, | ||
unsigned len) | ||
{ | ||
unsigned int prealign; | ||
unsigned int tail; | ||
|
||
#ifdef CRC_XOR | ||
crc ^= 0xffffffff; | ||
#endif | ||
|
||
if (len < VMX_ALIGN + VMX_ALIGN_MASK) { | ||
crc = crc32_align(crc, data, (unsigned long)len); | ||
goto out; | ||
} | ||
|
||
if ((unsigned long)data & VMX_ALIGN_MASK) { | ||
prealign = VMX_ALIGN - ((unsigned long)data & VMX_ALIGN_MASK); | ||
crc = crc32_align(crc, data, prealign); | ||
len -= prealign; | ||
data += prealign; | ||
} | ||
|
||
crc = __crc32_vpmsum(crc, data, (unsigned long)len & ~VMX_ALIGN_MASK); | ||
|
||
tail = len & VMX_ALIGN_MASK; | ||
if (tail) { | ||
data += len & ~VMX_ALIGN_MASK; | ||
crc = crc32_align(crc, data, tail); | ||
} | ||
|
||
out: | ||
#ifdef CRC_XOR | ||
crc ^= 0xffffffff; | ||
#endif | ||
|
||
return crc; | ||
} | ||
|
||
/* This wrapper function works around the fact that crc32_vpmsum | ||
* does not gracefully handle the case where the data pointer is NULL. There | ||
* may be room for performance improvement here. | ||
*/ | ||
uint32_t ceph_crc32c_ppc(uint32_t crc, unsigned char const *data, unsigned len) | ||
{ | ||
unsigned char *buf2; | ||
|
||
if (!data) { | ||
buf2 = malloc(len); | ||
bzero(buf2, len); | ||
crc = crc32_vpmsum(crc, buf2, len); | ||
free(buf2); | ||
} else { | ||
crc = crc32_vpmsum(crc, data, (unsigned long)len); | ||
} | ||
return crc; | ||
} | ||
|
||
#else /* HAVE_POWER8 */ | ||
|
||
/* This symbol has to exist on non-ppc architectures (and on legacy | ||
* ppc systems using power7 or below) in order to compile properly | ||
* there, even though it won't be called. | ||
*/ | ||
uint32_t ceph_crc32c_ppc(uint32_t crc, unsigned char const *data, unsigned len) | ||
{ | ||
return 0; | ||
} | ||
|
||
#endif /* HAVE_POWER8 */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
/* Copyright (C) 2017 International Business Machines Corp. | ||
* All rights reserved. | ||
* | ||
* This program is free software; you can redistribute it and/or | ||
* modify it under the terms of the GNU General Public License | ||
* as published by the Free Software Foundation; either version | ||
* 2 of the License, or (at your option) any later version. | ||
*/ | ||
#ifndef CEPH_COMMON_CRC32C_PPC_H | ||
#define CEPH_COMMON_CRC32C_PPC_H | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
extern uint32_t ceph_crc32c_ppc(uint32_t crc, unsigned char const *buffer, unsigned len); | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif | ||
|
||
#endif |
Oops, something went wrong.