int sptlrpc_get_bulk_checksum(struct ptlrpc_bulk_desc *desc, __u8 alg, void *buf, int buflen) { struct cfs_crypto_hash_desc *hdesc; int hashsize; unsigned int bufsize; int i, err; LASSERT(alg > BULK_HASH_ALG_NULL && alg < BULK_HASH_ALG_MAX); LASSERT(buflen >= 4); hdesc = cfs_crypto_hash_init(cfs_hash_alg_id[alg], NULL, 0); if (IS_ERR(hdesc)) { CERROR("Unable to initialize checksum hash %s\n", cfs_crypto_hash_name(cfs_hash_alg_id[alg])); return PTR_ERR(hdesc); } hashsize = cfs_crypto_hash_digestsize(cfs_hash_alg_id[alg]); for (i = 0; i < desc->bd_iov_count; i++) { cfs_crypto_hash_update_page(hdesc, BD_GET_KIOV(desc, i).bv_page, BD_GET_KIOV(desc, i).bv_offset & ~PAGE_MASK, BD_GET_KIOV(desc, i).bv_len); } if (hashsize > buflen) { unsigned char hashbuf[CFS_CRYPTO_HASH_DIGESTSIZE_MAX]; bufsize = sizeof(hashbuf); LASSERTF(bufsize >= hashsize, "bufsize = %u < hashsize %u\n", bufsize, hashsize); err = cfs_crypto_hash_final(hdesc, hashbuf, &bufsize); memcpy(buf, hashbuf, buflen); } else { bufsize = buflen; err = cfs_crypto_hash_final(hdesc, buf, &bufsize); } return err; }
int sptlrpc_get_bulk_checksum(struct ptlrpc_bulk_desc *desc, __u8 alg, void *buf, int buflen) { struct cfs_crypto_hash_desc *hdesc; int hashsize; char hashbuf[64]; unsigned int bufsize; int i, err; LASSERT(alg > BULK_HASH_ALG_NULL && alg < BULK_HASH_ALG_MAX); LASSERT(buflen >= 4); hdesc = cfs_crypto_hash_init(cfs_hash_alg_id[alg], NULL, 0); if (IS_ERR(hdesc)) { CERROR("Unable to initialize checksum hash %s\n", cfs_crypto_hash_name(cfs_hash_alg_id[alg])); return PTR_ERR(hdesc); } hashsize = cfs_crypto_hash_digestsize(cfs_hash_alg_id[alg]); for (i = 0; i < desc->bd_iov_count; i++) { cfs_crypto_hash_update_page(hdesc, desc->bd_iov[i].kiov_page, desc->bd_iov[i].kiov_offset & ~CFS_PAGE_MASK, desc->bd_iov[i].kiov_len); } if (hashsize > buflen) { bufsize = sizeof(hashbuf); err = cfs_crypto_hash_final(hdesc, (unsigned char *)hashbuf, &bufsize); memcpy(buf, hashbuf, buflen); } else { bufsize = buflen; err = cfs_crypto_hash_final(hdesc, (unsigned char *)buf, &bufsize); } if (err) cfs_crypto_hash_final(hdesc, NULL, NULL); return err; }
/** * Compute the speed of specified hash function * * Run a speed test on the given hash algorithm on buffer using a 1MB buffer * size. This is a reasonable buffer size for Lustre RPCs, even if the actual * RPC size is larger or smaller. * * The speed is stored internally in the cfs_crypto_hash_speeds[] array, and * is available through the cfs_crypto_hash_speed() function. * * This function needs to stay the same as obd_t10_performance_test() so that * the speeds are comparable. * * \param[in] hash_alg hash algorithm id (CFS_HASH_ALG_*) * \param[in] buf data buffer on which to compute the hash * \param[in] buf_len length of \buf on which to compute hash */ static void cfs_crypto_performance_test(enum cfs_crypto_hash_alg hash_alg) { int buf_len = max(PAGE_SIZE, 1048576UL); void *buf; unsigned long start, end; int err = 0; unsigned long bcount; struct page *page; unsigned char hash[CFS_CRYPTO_HASH_DIGESTSIZE_MAX]; unsigned int hash_len = sizeof(hash); page = alloc_page(GFP_KERNEL); if (page == NULL) { err = -ENOMEM; goto out_err; } buf = kmap(page); memset(buf, 0xAD, PAGE_SIZE); kunmap(page); for (start = jiffies, end = start + msecs_to_jiffies(MSEC_PER_SEC / 4), bcount = 0; time_before(jiffies, end) && err == 0; bcount++) { struct ahash_request *req; int i; req = cfs_crypto_hash_init(hash_alg, NULL, 0); if (IS_ERR(req)) { err = PTR_ERR(req); break; } for (i = 0; i < buf_len / PAGE_SIZE; i++) { err = cfs_crypto_hash_update_page(req, page, 0, PAGE_SIZE); if (err != 0) break; } err = cfs_crypto_hash_final(req, hash, &hash_len); if (err != 0) break; } end = jiffies; __free_page(page); out_err: if (err != 0) { cfs_crypto_hash_speeds[hash_alg] = err; CDEBUG(D_INFO, "Crypto hash algorithm %s test error: rc = %d\n", cfs_crypto_hash_name(hash_alg), err); } else { unsigned long tmp; tmp = ((bcount * buf_len / jiffies_to_msecs(end - start)) * 1000) / (1024 * 1024); cfs_crypto_hash_speeds[hash_alg] = (int)tmp; CDEBUG(D_CONFIG, "Crypto hash algorithm %s speed = %d MB/s\n", cfs_crypto_hash_name(hash_alg), cfs_crypto_hash_speeds[hash_alg]); } }