X-Git-Url: https://git.archive.openwrt.org/?p=15.05%2Fopenwrt.git;a=blobdiff_plain;f=target%2Flinux%2Fgeneric%2Ffiles%2Fcrypto%2Focf%2Fcrypto.c;fp=target%2Flinux%2Fgeneric%2Ffiles%2Fcrypto%2Focf%2Fcrypto.c;h=f48210d06219a2f77f1f3ce95696c41e991f1b41;hp=ccd5a4bfab3f1948246ff0d9411caa55375b8f1e;hb=56d7544ebb722827e046818a7a030caaec1e7ed6;hpb=172c2218549787eaf3afdbd6f12b7e27bd4169df diff --git a/target/linux/generic/files/crypto/ocf/crypto.c b/target/linux/generic/files/crypto/ocf/crypto.c index ccd5a4bfab..f48210d062 100644 --- a/target/linux/generic/files/crypto/ocf/crypto.c +++ b/target/linux/generic/files/crypto/ocf/crypto.c @@ -64,10 +64,8 @@ __FBSDID("$FreeBSD: src/sys/opencrypto/crypto.c,v 1.16 2005/01/07 02:29:16 imp E #include -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,33)) -#include -#else -#include +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38) && !defined(AUTOCONF_INCLUDED) +#include #endif #include #include @@ -76,7 +74,9 @@ __FBSDID("$FreeBSD: src/sys/opencrypto/crypto.c,v 1.16 2005/01/07 02:29:16 imp E #include #include #include -#include +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,4) +#include +#endif #include /* @@ -156,9 +156,8 @@ static int crypto_drivers_num = 0; * have one per-queue but having one simplifies handling of block/unblock * operations. */ -static int crp_sleep = 0; -static LIST_HEAD(crp_q); /* request queues */ -static LIST_HEAD(crp_kq); +static LIST_HEAD(crp_q); /* crypto request queue */ +static LIST_HEAD(crp_kq); /* asym request queue */ static spinlock_t crypto_q_lock; @@ -213,11 +212,6 @@ static struct kmem_cache *cryptop_zone; static struct kmem_cache *cryptodesc_zone; #endif -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) -#include -#define kill_proc(p,s,v) send_sig(s,find_task_by_vpid(p),0) -#endif - #define debug crypto_debug int crypto_debug = 0; module_param(crypto_debug, int, 0644); @@ -278,11 +272,13 @@ module_param(crypto_max_loopcount, int, 0644); MODULE_PARM_DESC(crypto_max_loopcount, "Maximum number of crypto ops to do before yielding to other processes"); -static pid_t cryptoproc = (pid_t) -1; -static struct completion cryptoproc_exited; +#ifndef CONFIG_NR_CPUS +#define CONFIG_NR_CPUS 1 +#endif + +static struct task_struct *cryptoproc[CONFIG_NR_CPUS]; +static struct task_struct *cryptoretproc[CONFIG_NR_CPUS]; static DECLARE_WAIT_QUEUE_HEAD(cryptoproc_wait); -static pid_t cryptoretproc = (pid_t) -1; -static struct completion cryptoretproc_exited; static DECLARE_WAIT_QUEUE_HEAD(cryptoretproc_wait); static int crypto_proc(void *arg); @@ -318,6 +314,7 @@ driver_suitable(const struct cryptocap *cap, const struct cryptoini *cri) return 1; } + /* * Select a driver for a new session that supports the specified * algorithms and, optionally, is constrained according to the flags. @@ -791,8 +788,7 @@ crypto_unblock(u_int32_t driverid, int what) cap->cc_unkqblocked = 0; crypto_all_kqblocked = 0; } - if (crp_sleep) - wake_up_interruptible(&cryptoproc_wait); + wake_up_interruptible(&cryptoproc_wait); err = 0; } else err = EINVAL; @@ -817,8 +813,8 @@ crypto_dispatch(struct cryptop *crp) CRYPTO_Q_LOCK(); if (crypto_q_cnt >= crypto_q_max) { - CRYPTO_Q_UNLOCK(); cryptostats.cs_drops++; + CRYPTO_Q_UNLOCK(); return ENOMEM; } crypto_q_cnt++; @@ -865,8 +861,7 @@ crypto_dispatch(struct cryptop *crp) TAILQ_INSERT_TAIL(&crp_q, crp, crp_next); result = 0; } - if (crp_sleep) - wake_up_interruptible(&cryptoproc_wait); + wake_up_interruptible(&cryptoproc_wait); CRYPTO_Q_UNLOCK(); return result; } @@ -887,8 +882,7 @@ crypto_kdispatch(struct cryptkop *krp) if (error == ERESTART) { CRYPTO_Q_LOCK(); TAILQ_INSERT_TAIL(&crp_kq, krp, krp_next); - if (crp_sleep) - wake_up_interruptible(&cryptoproc_wait); + wake_up_interruptible(&cryptoproc_wait); CRYPTO_Q_UNLOCK(); error = 0; } @@ -1186,8 +1180,7 @@ crypto_done(struct cryptop *crp) * Normal case; queue the callback for the thread. */ CRYPTO_RETQ_LOCK(); - if (CRYPTO_RETQ_EMPTY()) - wake_up_interruptible(&cryptoretproc_wait);/* shared wait channel */ + wake_up_interruptible(&cryptoretproc_wait);/* shared wait channel */ TAILQ_INSERT_TAIL(&crp_ret_q, crp, crp_next); CRYPTO_RETQ_UNLOCK(); } @@ -1237,8 +1230,7 @@ crypto_kdone(struct cryptkop *krp) * Normal case; queue the callback for the thread. */ CRYPTO_RETQ_LOCK(); - if (CRYPTO_RETQ_EMPTY()) - wake_up_interruptible(&cryptoretproc_wait);/* shared wait channel */ + wake_up_interruptible(&cryptoretproc_wait);/* shared wait channel */ TAILQ_INSERT_TAIL(&crp_ret_kq, krp, krp_next); CRYPTO_RETQ_UNLOCK(); } @@ -1281,7 +1273,7 @@ crypto_proc(void *arg) unsigned long q_flags; int loopcount = 0; - ocf_daemonize("crypto"); + set_current_state(TASK_INTERRUPTIBLE); CRYPTO_Q_LOCK(); for (;;) { @@ -1435,12 +1427,10 @@ crypto_proc(void *arg) list_empty(&crp_kq), crypto_all_kqblocked); loopcount = 0; CRYPTO_Q_UNLOCK(); - crp_sleep = 1; wait_event_interruptible(cryptoproc_wait, !(list_empty(&crp_q) || crypto_all_qblocked) || !(list_empty(&crp_kq) || crypto_all_kqblocked) || - cryptoproc == (pid_t) -1); - crp_sleep = 0; + kthread_should_stop()); if (signal_pending (current)) { #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) spin_lock_irq(¤t->sigmask_lock); @@ -1452,7 +1442,7 @@ crypto_proc(void *arg) } CRYPTO_Q_LOCK(); dprintk("%s - awake\n", __FUNCTION__); - if (cryptoproc == (pid_t) -1) + if (kthread_should_stop()) break; cryptostats.cs_intrs++; } else if (loopcount > crypto_max_loopcount) { @@ -1461,12 +1451,14 @@ crypto_proc(void *arg) * been using the CPU exclusively for a while. */ loopcount = 0; + CRYPTO_Q_UNLOCK(); schedule(); + CRYPTO_Q_LOCK(); } loopcount++; } CRYPTO_Q_UNLOCK(); - complete_and_exit(&cryptoproc_exited, 0); + return 0; } /* @@ -1481,7 +1473,7 @@ crypto_ret_proc(void *arg) struct cryptkop *krpt; unsigned long r_flags; - ocf_daemonize("crypto_ret"); + set_current_state(TASK_INTERRUPTIBLE); CRYPTO_RETQ_LOCK(); for (;;) { @@ -1516,9 +1508,9 @@ crypto_ret_proc(void *arg) dprintk("%s - sleeping\n", __FUNCTION__); CRYPTO_RETQ_UNLOCK(); wait_event_interruptible(cryptoretproc_wait, - cryptoretproc == (pid_t) -1 || !list_empty(&crp_ret_q) || - !list_empty(&crp_ret_kq)); + !list_empty(&crp_ret_kq) || + kthread_should_stop()); if (signal_pending (current)) { #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) spin_lock_irq(¤t->sigmask_lock); @@ -1530,7 +1522,7 @@ crypto_ret_proc(void *arg) } CRYPTO_RETQ_LOCK(); dprintk("%s - awake\n", __FUNCTION__); - if (cryptoretproc == (pid_t) -1) { + if (kthread_should_stop()) { dprintk("%s - EXITING!\n", __FUNCTION__); break; } @@ -1538,7 +1530,7 @@ crypto_ret_proc(void *arg) } } CRYPTO_RETQ_UNLOCK(); - complete_and_exit(&cryptoretproc_exited, 0); + return 0; } @@ -1644,6 +1636,7 @@ static int crypto_init(void) { int error; + unsigned long cpu; dprintk("%s(%p)\n", __FUNCTION__, (void *) crypto_init); @@ -1686,25 +1679,28 @@ crypto_init(void) memset(crypto_drivers, 0, crypto_drivers_num * sizeof(struct cryptocap)); - init_completion(&cryptoproc_exited); - init_completion(&cryptoretproc_exited); - - cryptoproc = 0; /* to avoid race condition where proc runs first */ - cryptoproc = kernel_thread(crypto_proc, NULL, CLONE_FS|CLONE_FILES); - if (cryptoproc < 0) { - error = cryptoproc; - printk("crypto: crypto_init cannot start crypto thread; error %d", - error); - goto bad; - } - - cryptoretproc = 0; /* to avoid race condition where proc runs first */ - cryptoretproc = kernel_thread(crypto_ret_proc, NULL, CLONE_FS|CLONE_FILES); - if (cryptoretproc < 0) { - error = cryptoretproc; - printk("crypto: crypto_init cannot start cryptoret thread; error %d", + ocf_for_each_cpu(cpu) { + cryptoproc[cpu] = kthread_create(crypto_proc, (void *) cpu, + "ocf_%d", (int) cpu); + if (IS_ERR(cryptoproc[cpu])) { + error = PTR_ERR(cryptoproc[cpu]); + printk("crypto: crypto_init cannot start crypto thread; error %d", error); - goto bad; + goto bad; + } + kthread_bind(cryptoproc[cpu], cpu); + wake_up_process(cryptoproc[cpu]); + + cryptoretproc[cpu] = kthread_create(crypto_ret_proc, (void *) cpu, + "ocf_ret_%d", (int) cpu); + if (IS_ERR(cryptoretproc[cpu])) { + error = PTR_ERR(cryptoretproc[cpu]); + printk("crypto: crypto_init cannot start cryptoret thread; error %d", + error); + goto bad; + } + kthread_bind(cryptoretproc[cpu], cpu); + wake_up_process(cryptoretproc[cpu]); } return 0; @@ -1717,34 +1713,17 @@ bad: static void crypto_exit(void) { - pid_t p; - unsigned long d_flags; + int cpu; dprintk("%s()\n", __FUNCTION__); /* * Terminate any crypto threads. */ - - CRYPTO_DRIVER_LOCK(); - p = cryptoproc; - cryptoproc = (pid_t) -1; - kill_proc(p, SIGTERM, 1); - wake_up_interruptible(&cryptoproc_wait); - CRYPTO_DRIVER_UNLOCK(); - - wait_for_completion(&cryptoproc_exited); - - CRYPTO_DRIVER_LOCK(); - p = cryptoretproc; - cryptoretproc = (pid_t) -1; - kill_proc(p, SIGTERM, 1); - wake_up_interruptible(&cryptoretproc_wait); - CRYPTO_DRIVER_UNLOCK(); - - wait_for_completion(&cryptoretproc_exited); - - /* XXX flush queues??? */ + ocf_for_each_cpu(cpu) { + kthread_stop(cryptoproc[cpu]); + kthread_stop(cryptoretproc[cpu]); + } /* * Reclaim dynamically allocated resources.