X-Git-Url: https://git.rohieb.name/openwrt.git/blobdiff_plain/c5552ad03973839d83d32d7108f20c00f192633b..91f1cdc854ccc58fc92274eb848281e5d500a3f1:/target/linux/generic/files/crypto/ocf/crypto.c diff --git a/target/linux/generic/files/crypto/ocf/crypto.c b/target/linux/generic/files/crypto/ocf/crypto.c index 9735f0ce9..f48210d06 100644 --- a/target/linux/generic/files/crypto/ocf/crypto.c +++ b/target/linux/generic/files/crypto/ocf/crypto.c @@ -63,7 +63,8 @@ __FBSDID("$FreeBSD: src/sys/opencrypto/crypto.c,v 1.16 2005/01/07 02:29:16 imp E */ -#ifndef AUTOCONF_INCLUDED +#include +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38) && !defined(AUTOCONF_INCLUDED) #include #endif #include @@ -73,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 /* @@ -153,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; @@ -210,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); @@ -275,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); @@ -315,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. @@ -788,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; @@ -814,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++; @@ -862,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; } @@ -884,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; } @@ -1183,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(); } @@ -1234,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(); } @@ -1278,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 (;;) { @@ -1432,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); @@ -1449,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) { @@ -1458,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; } /* @@ -1478,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 (;;) { @@ -1513,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); @@ -1527,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; } @@ -1535,7 +1530,7 @@ crypto_ret_proc(void *arg) } } CRYPTO_RETQ_UNLOCK(); - complete_and_exit(&cryptoretproc_exited, 0); + return 0; } @@ -1641,6 +1636,7 @@ static int crypto_init(void) { int error; + unsigned long cpu; dprintk("%s(%p)\n", __FUNCTION__, (void *) crypto_init); @@ -1683,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; @@ -1714,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.