Root/target/linux/generic-2.6/files/crypto/ocf/ocf-bench.c

1/*
2 * A loadable module that benchmarks the OCF crypto speed from kernel space.
3 *
4 * Copyright (C) 2004-2007 David McCullough <david_mccullough@securecomputing.com>
5 *
6 * LICENSE TERMS
7 *
8 * The free distribution and use of this software in both source and binary
9 * form is allowed (with or without changes) provided that:
10 *
11 * 1. distributions of this source code include the above copyright
12 * notice, this list of conditions and the following disclaimer;
13 *
14 * 2. distributions in binary form include the above copyright
15 * notice, this list of conditions and the following disclaimer
16 * in the documentation and/or other associated materials;
17 *
18 * 3. the copyright holder's name is not used to endorse products
19 * built using this software without specific written permission.
20 *
21 * ALTERNATIVELY, provided that this notice is retained in full, this product
22 * may be distributed under the terms of the GNU General Public License (GPL),
23 * in which case the provisions of the GPL apply INSTEAD OF those given above.
24 *
25 * DISCLAIMER
26 *
27 * This software is provided 'as is' with no explicit or implied warranties
28 * in respect of its properties, including, but not limited to, correctness
29 * and/or fitness for purpose.
30 */
31
32
33#ifndef AUTOCONF_INCLUDED
34#include <linux/config.h>
35#endif
36#include <linux/module.h>
37#include <linux/init.h>
38#include <linux/list.h>
39#include <linux/slab.h>
40#include <linux/wait.h>
41#include <linux/sched.h>
42#include <linux/spinlock.h>
43#include <linux/version.h>
44#include <linux/interrupt.h>
45#include <cryptodev.h>
46
47#ifdef I_HAVE_AN_XSCALE_WITH_INTEL_SDK
48#define BENCH_IXP_ACCESS_LIB 1
49#endif
50#ifdef BENCH_IXP_ACCESS_LIB
51#include <IxTypes.h>
52#include <IxOsBuffMgt.h>
53#include <IxNpeDl.h>
54#include <IxCryptoAcc.h>
55#include <IxQMgr.h>
56#include <IxOsServices.h>
57#include <IxOsCacheMMU.h>
58#endif
59
60/*
61 * support for access lib version 1.4
62 */
63#ifndef IX_MBUF_PRIV
64#define IX_MBUF_PRIV(x) ((x)->priv)
65#endif
66
67/*
68 * the number of simultaneously active requests
69 */
70static int request_q_len = 20;
71module_param(request_q_len, int, 0);
72MODULE_PARM_DESC(request_q_len, "Number of outstanding requests");
73/*
74 * how many requests we want to have processed
75 */
76static int request_num = 1024;
77module_param(request_num, int, 0);
78MODULE_PARM_DESC(request_num, "run for at least this many requests");
79/*
80 * the size of each request
81 */
82static int request_size = 1500;
83module_param(request_size, int, 0);
84MODULE_PARM_DESC(request_size, "size of each request");
85
86/*
87 * a structure for each request
88 */
89typedef struct {
90    struct work_struct work;
91#ifdef BENCH_IXP_ACCESS_LIB
92    IX_MBUF mbuf;
93#endif
94    unsigned char *buffer;
95} request_t;
96
97static request_t *requests;
98
99static int outstanding;
100static int total;
101
102/*************************************************************************/
103/*
104 * OCF benchmark routines
105 */
106
107static uint64_t ocf_cryptoid;
108static int ocf_init(void);
109static int ocf_cb(struct cryptop *crp);
110static void ocf_request(void *arg);
111#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
112static void ocf_request_wq(struct work_struct *work);
113#endif
114
115static int
116ocf_init(void)
117{
118    int error;
119    struct cryptoini crie, cria;
120    struct cryptodesc crda, crde;
121
122    memset(&crie, 0, sizeof(crie));
123    memset(&cria, 0, sizeof(cria));
124    memset(&crde, 0, sizeof(crde));
125    memset(&crda, 0, sizeof(crda));
126
127    cria.cri_alg = CRYPTO_SHA1_HMAC;
128    cria.cri_klen = 20 * 8;
129    cria.cri_key = "0123456789abcdefghij";
130
131    crie.cri_alg = CRYPTO_3DES_CBC;
132    crie.cri_klen = 24 * 8;
133    crie.cri_key = "0123456789abcdefghijklmn";
134
135    crie.cri_next = &cria;
136
137    error = crypto_newsession(&ocf_cryptoid, &crie, 0);
138    if (error) {
139        printk("crypto_newsession failed %d\n", error);
140        return -1;
141    }
142    return 0;
143}
144
145static int
146ocf_cb(struct cryptop *crp)
147{
148    request_t *r = (request_t *) crp->crp_opaque;
149
150    if (crp->crp_etype)
151        printk("Error in OCF processing: %d\n", crp->crp_etype);
152    total++;
153    crypto_freereq(crp);
154    crp = NULL;
155
156    if (total > request_num) {
157        outstanding--;
158        return 0;
159    }
160
161#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
162    INIT_WORK(&r->work, ocf_request_wq);
163#else
164    INIT_WORK(&r->work, ocf_request, r);
165#endif
166    schedule_work(&r->work);
167    return 0;
168}
169
170
171static void
172ocf_request(void *arg)
173{
174    request_t *r = arg;
175    struct cryptop *crp = crypto_getreq(2);
176    struct cryptodesc *crde, *crda;
177
178    if (!crp) {
179        outstanding--;
180        return;
181    }
182
183    crde = crp->crp_desc;
184    crda = crde->crd_next;
185
186    crda->crd_skip = 0;
187    crda->crd_flags = 0;
188    crda->crd_len = request_size;
189    crda->crd_inject = request_size;
190    crda->crd_alg = CRYPTO_SHA1_HMAC;
191    crda->crd_key = "0123456789abcdefghij";
192    crda->crd_klen = 20 * 8;
193
194    crde->crd_skip = 0;
195    crde->crd_flags = CRD_F_IV_EXPLICIT | CRD_F_ENCRYPT;
196    crde->crd_len = request_size;
197    crde->crd_inject = request_size;
198    crde->crd_alg = CRYPTO_3DES_CBC;
199    crde->crd_key = "0123456789abcdefghijklmn";
200    crde->crd_klen = 24 * 8;
201
202    crp->crp_ilen = request_size + 64;
203    crp->crp_flags = CRYPTO_F_CBIMM;
204    crp->crp_buf = (caddr_t) r->buffer;
205    crp->crp_callback = ocf_cb;
206    crp->crp_sid = ocf_cryptoid;
207    crp->crp_opaque = (caddr_t) r;
208    crypto_dispatch(crp);
209}
210
211#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
212static void
213ocf_request_wq(struct work_struct *work)
214{
215    request_t *r = container_of(work, request_t, work);
216    ocf_request(r);
217}
218#endif
219
220/*************************************************************************/
221#ifdef BENCH_IXP_ACCESS_LIB
222/*************************************************************************/
223/*
224 * CryptoAcc benchmark routines
225 */
226
227static IxCryptoAccCtx ixp_ctx;
228static UINT32 ixp_ctx_id;
229static IX_MBUF ixp_pri;
230static IX_MBUF ixp_sec;
231static int ixp_registered = 0;
232
233static void ixp_register_cb(UINT32 ctx_id, IX_MBUF *bufp,
234                    IxCryptoAccStatus status);
235static void ixp_perform_cb(UINT32 ctx_id, IX_MBUF *sbufp, IX_MBUF *dbufp,
236                    IxCryptoAccStatus status);
237static void ixp_request(void *arg);
238#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
239static void ixp_request_wq(struct work_struct *work);
240#endif
241
242static int
243ixp_init(void)
244{
245    IxCryptoAccStatus status;
246
247    ixp_ctx.cipherCtx.cipherAlgo = IX_CRYPTO_ACC_CIPHER_3DES;
248    ixp_ctx.cipherCtx.cipherMode = IX_CRYPTO_ACC_MODE_CBC;
249    ixp_ctx.cipherCtx.cipherKeyLen = 24;
250    ixp_ctx.cipherCtx.cipherBlockLen = IX_CRYPTO_ACC_DES_BLOCK_64;
251    ixp_ctx.cipherCtx.cipherInitialVectorLen = IX_CRYPTO_ACC_DES_IV_64;
252    memcpy(ixp_ctx.cipherCtx.key.cipherKey, "0123456789abcdefghijklmn", 24);
253
254    ixp_ctx.authCtx.authAlgo = IX_CRYPTO_ACC_AUTH_SHA1;
255    ixp_ctx.authCtx.authDigestLen = 12;
256    ixp_ctx.authCtx.aadLen = 0;
257    ixp_ctx.authCtx.authKeyLen = 20;
258    memcpy(ixp_ctx.authCtx.key.authKey, "0123456789abcdefghij", 20);
259
260    ixp_ctx.useDifferentSrcAndDestMbufs = 0;
261    ixp_ctx.operation = IX_CRYPTO_ACC_OP_ENCRYPT_AUTH ;
262
263    IX_MBUF_MLEN(&ixp_pri) = IX_MBUF_PKT_LEN(&ixp_pri) = 128;
264    IX_MBUF_MDATA(&ixp_pri) = (unsigned char *) kmalloc(128, SLAB_ATOMIC);
265    IX_MBUF_MLEN(&ixp_sec) = IX_MBUF_PKT_LEN(&ixp_sec) = 128;
266    IX_MBUF_MDATA(&ixp_sec) = (unsigned char *) kmalloc(128, SLAB_ATOMIC);
267
268    status = ixCryptoAccCtxRegister(&ixp_ctx, &ixp_pri, &ixp_sec,
269            ixp_register_cb, ixp_perform_cb, &ixp_ctx_id);
270
271    if (IX_CRYPTO_ACC_STATUS_SUCCESS == status) {
272        while (!ixp_registered)
273            schedule();
274        return ixp_registered < 0 ? -1 : 0;
275    }
276
277    printk("ixp: ixCryptoAccCtxRegister failed %d\n", status);
278    return -1;
279}
280
281static void
282ixp_register_cb(UINT32 ctx_id, IX_MBUF *bufp, IxCryptoAccStatus status)
283{
284    if (bufp) {
285        IX_MBUF_MLEN(bufp) = IX_MBUF_PKT_LEN(bufp) = 0;
286        kfree(IX_MBUF_MDATA(bufp));
287        IX_MBUF_MDATA(bufp) = NULL;
288    }
289
290    if (IX_CRYPTO_ACC_STATUS_WAIT == status)
291        return;
292    if (IX_CRYPTO_ACC_STATUS_SUCCESS == status)
293        ixp_registered = 1;
294    else
295        ixp_registered = -1;
296}
297
298static void
299ixp_perform_cb(
300    UINT32 ctx_id,
301    IX_MBUF *sbufp,
302    IX_MBUF *dbufp,
303    IxCryptoAccStatus status)
304{
305    request_t *r = NULL;
306
307    total++;
308    if (total > request_num) {
309        outstanding--;
310        return;
311    }
312
313    if (!sbufp || !(r = IX_MBUF_PRIV(sbufp))) {
314        printk("crappo %p %p\n", sbufp, r);
315        outstanding--;
316        return;
317    }
318
319#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
320    INIT_WORK(&r->work, ixp_request_wq);
321#else
322    INIT_WORK(&r->work, ixp_request, r);
323#endif
324    schedule_work(&r->work);
325}
326
327static void
328ixp_request(void *arg)
329{
330    request_t *r = arg;
331    IxCryptoAccStatus status;
332
333    memset(&r->mbuf, 0, sizeof(r->mbuf));
334    IX_MBUF_MLEN(&r->mbuf) = IX_MBUF_PKT_LEN(&r->mbuf) = request_size + 64;
335    IX_MBUF_MDATA(&r->mbuf) = r->buffer;
336    IX_MBUF_PRIV(&r->mbuf) = r;
337    status = ixCryptoAccAuthCryptPerform(ixp_ctx_id, &r->mbuf, NULL,
338            0, request_size, 0, request_size, request_size, r->buffer);
339    if (IX_CRYPTO_ACC_STATUS_SUCCESS != status) {
340        printk("status1 = %d\n", status);
341        outstanding--;
342        return;
343    }
344    return;
345}
346
347#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
348static void
349ixp_request_wq(struct work_struct *work)
350{
351    request_t *r = container_of(work, request_t, work);
352    ixp_request(r);
353}
354#endif
355
356/*************************************************************************/
357#endif /* BENCH_IXP_ACCESS_LIB */
358/*************************************************************************/
359
360int
361ocfbench_init(void)
362{
363    int i, jstart, jstop;
364
365    printk("Crypto Speed tests\n");
366
367    requests = kmalloc(sizeof(request_t) * request_q_len, GFP_KERNEL);
368    if (!requests) {
369        printk("malloc failed\n");
370        return -EINVAL;
371    }
372
373    for (i = 0; i < request_q_len; i++) {
374        /* +64 for return data */
375        requests[i].buffer = kmalloc(request_size + 128, GFP_DMA);
376        if (!requests[i].buffer) {
377            printk("malloc failed\n");
378            return -EINVAL;
379        }
380        memset(requests[i].buffer, '0' + i, request_size + 128);
381    }
382
383    /*
384     * OCF benchmark
385     */
386    printk("OCF: testing ...\n");
387    ocf_init();
388    total = outstanding = 0;
389    jstart = jiffies;
390    for (i = 0; i < request_q_len; i++) {
391        outstanding++;
392        ocf_request(&requests[i]);
393    }
394    while (outstanding > 0)
395        schedule();
396    jstop = jiffies;
397
398    printk("OCF: %d requests of %d bytes in %d jiffies\n", total, request_size,
399            jstop - jstart);
400
401#ifdef BENCH_IXP_ACCESS_LIB
402    /*
403     * IXP benchmark
404     */
405    printk("IXP: testing ...\n");
406    ixp_init();
407    total = outstanding = 0;
408    jstart = jiffies;
409    for (i = 0; i < request_q_len; i++) {
410        outstanding++;
411        ixp_request(&requests[i]);
412    }
413    while (outstanding > 0)
414        schedule();
415    jstop = jiffies;
416
417    printk("IXP: %d requests of %d bytes in %d jiffies\n", total, request_size,
418            jstop - jstart);
419#endif /* BENCH_IXP_ACCESS_LIB */
420
421    for (i = 0; i < request_q_len; i++)
422        kfree(requests[i].buffer);
423    kfree(requests);
424    return -EINVAL; /* always fail to load so it can be re-run quickly ;-) */
425}
426
427static void __exit ocfbench_exit(void)
428{
429}
430
431module_init(ocfbench_init);
432module_exit(ocfbench_exit);
433
434MODULE_LICENSE("BSD");
435MODULE_AUTHOR("David McCullough <david_mccullough@securecomputing.com>");
436MODULE_DESCRIPTION("Benchmark various in-kernel crypto speeds");
437

Archive Download this file



interactive