diff options
Diffstat (limited to 'drivers/net/wireguard/queueing.c')
| -rw-r--r-- | drivers/net/wireguard/queueing.c | 53 | 
1 files changed, 53 insertions, 0 deletions
| diff --git a/drivers/net/wireguard/queueing.c b/drivers/net/wireguard/queueing.c new file mode 100644 index 000000000000..5c964fcb994e --- /dev/null +++ b/drivers/net/wireguard/queueing.c @@ -0,0 +1,53 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2015-2019 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved. + */ + +#include "queueing.h" + +struct multicore_worker __percpu * +wg_packet_percpu_multicore_worker_alloc(work_func_t function, void *ptr) +{ +	int cpu; +	struct multicore_worker __percpu *worker = +		alloc_percpu(struct multicore_worker); + +	if (!worker) +		return NULL; + +	for_each_possible_cpu(cpu) { +		per_cpu_ptr(worker, cpu)->ptr = ptr; +		INIT_WORK(&per_cpu_ptr(worker, cpu)->work, function); +	} +	return worker; +} + +int wg_packet_queue_init(struct crypt_queue *queue, work_func_t function, +			 bool multicore, unsigned int len) +{ +	int ret; + +	memset(queue, 0, sizeof(*queue)); +	ret = ptr_ring_init(&queue->ring, len, GFP_KERNEL); +	if (ret) +		return ret; +	if (function) { +		if (multicore) { +			queue->worker = wg_packet_percpu_multicore_worker_alloc( +				function, queue); +			if (!queue->worker) +				return -ENOMEM; +		} else { +			INIT_WORK(&queue->work, function); +		} +	} +	return 0; +} + +void wg_packet_queue_free(struct crypt_queue *queue, bool multicore) +{ +	if (multicore) +		free_percpu(queue->worker); +	WARN_ON(!__ptr_ring_empty(&queue->ring)); +	ptr_ring_cleanup(&queue->ring, NULL); +} | 
