xref: /illumos-gate/usr/src/uts/common/sys/taskq_impl.h (revision 641097441a6e36fb83135a28c834761ecbb80d36)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
52e0c549eSJonathan Adams  * Common Development and Distribution License (the "License").
62e0c549eSJonathan Adams  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
22*64109744SChris Horne  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate #ifndef	_SYS_TASKQ_IMPL_H
277c478bd9Sstevel@tonic-gate #define	_SYS_TASKQ_IMPL_H
287c478bd9Sstevel@tonic-gate 
297c478bd9Sstevel@tonic-gate #include <sys/taskq.h>
3035a5a358SJonathan Adams #include <sys/inttypes.h>
317c478bd9Sstevel@tonic-gate #include <sys/vmem.h>
3235a5a358SJonathan Adams #include <sys/list.h>
337c478bd9Sstevel@tonic-gate #include <sys/kstat.h>
347c478bd9Sstevel@tonic-gate 
357c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
367c478bd9Sstevel@tonic-gate extern "C" {
377c478bd9Sstevel@tonic-gate #endif
387c478bd9Sstevel@tonic-gate 
397c478bd9Sstevel@tonic-gate typedef struct taskq_bucket taskq_bucket_t;
407c478bd9Sstevel@tonic-gate 
417c478bd9Sstevel@tonic-gate typedef struct taskq_ent {
427c478bd9Sstevel@tonic-gate 	struct taskq_ent	*tqent_next;
437c478bd9Sstevel@tonic-gate 	struct taskq_ent	*tqent_prev;
447c478bd9Sstevel@tonic-gate 	task_func_t		*tqent_func;
457c478bd9Sstevel@tonic-gate 	void			*tqent_arg;
467c478bd9Sstevel@tonic-gate 	taskq_bucket_t		*tqent_bucket;
477c478bd9Sstevel@tonic-gate 	kthread_t		*tqent_thread;
487c478bd9Sstevel@tonic-gate 	kcondvar_t		tqent_cv;
497c478bd9Sstevel@tonic-gate } taskq_ent_t;
507c478bd9Sstevel@tonic-gate 
517c478bd9Sstevel@tonic-gate /*
527c478bd9Sstevel@tonic-gate  * Taskq Statistics fields are not protected by any locks.
537c478bd9Sstevel@tonic-gate  */
547c478bd9Sstevel@tonic-gate typedef struct tqstat {
557c478bd9Sstevel@tonic-gate 	uint_t		tqs_hits;
567c478bd9Sstevel@tonic-gate 	uint_t		tqs_misses;
577c478bd9Sstevel@tonic-gate 	uint_t		tqs_overflow;	/* no threads to allocate   */
587c478bd9Sstevel@tonic-gate 	uint_t		tqs_tcreates;	/* threads created 	*/
597c478bd9Sstevel@tonic-gate 	uint_t		tqs_tdeaths;	/* threads died		*/
607c478bd9Sstevel@tonic-gate 	uint_t		tqs_maxthreads;	/* max # of alive threads */
617c478bd9Sstevel@tonic-gate 	uint_t		tqs_nomem;	/* # of times there were no memory */
627c478bd9Sstevel@tonic-gate 	uint_t		tqs_disptcreates;
637c478bd9Sstevel@tonic-gate } tqstat_t;
647c478bd9Sstevel@tonic-gate 
657c478bd9Sstevel@tonic-gate /*
667c478bd9Sstevel@tonic-gate  * Per-CPU hash bucket manages taskq_bent_t structures using freelist.
677c478bd9Sstevel@tonic-gate  */
687c478bd9Sstevel@tonic-gate struct taskq_bucket {
697c478bd9Sstevel@tonic-gate 	kmutex_t	tqbucket_lock;
707c478bd9Sstevel@tonic-gate 	taskq_t		*tqbucket_taskq;	/* Enclosing taskq */
717c478bd9Sstevel@tonic-gate 	taskq_ent_t	tqbucket_freelist;
727c478bd9Sstevel@tonic-gate 	uint_t		tqbucket_nalloc;	/* # of allocated entries */
737c478bd9Sstevel@tonic-gate 	uint_t		tqbucket_nfree;		/* # of free entries */
747c478bd9Sstevel@tonic-gate 	kcondvar_t	tqbucket_cv;
757c478bd9Sstevel@tonic-gate 	ushort_t	tqbucket_flags;
767c478bd9Sstevel@tonic-gate 	hrtime_t	tqbucket_totaltime;
777c478bd9Sstevel@tonic-gate 	tqstat_t	tqbucket_stat;
787c478bd9Sstevel@tonic-gate };
797c478bd9Sstevel@tonic-gate 
807c478bd9Sstevel@tonic-gate /*
817c478bd9Sstevel@tonic-gate  * Bucket flags.
827c478bd9Sstevel@tonic-gate  */
837c478bd9Sstevel@tonic-gate #define	TQBUCKET_CLOSE		0x01
847c478bd9Sstevel@tonic-gate #define	TQBUCKET_SUSPEND	0x02
857c478bd9Sstevel@tonic-gate 
8635a5a358SJonathan Adams #define	TASKQ_INTERFACE_FLAGS	0x0000ffff	/* defined in <sys/taskq.h> */
8735a5a358SJonathan Adams 
887c478bd9Sstevel@tonic-gate /*
897c478bd9Sstevel@tonic-gate  * taskq implementation flags: bit range 16-31
907c478bd9Sstevel@tonic-gate  */
9135a5a358SJonathan Adams #define	TASKQ_CHANGING		0x00010000	/* nthreads != target */
9235a5a358SJonathan Adams #define	TASKQ_SUSPENDED		0x00020000	/* taskq is suspended */
9335a5a358SJonathan Adams #define	TASKQ_NOINSTANCE	0x00040000	/* no instance number */
9435a5a358SJonathan Adams #define	TASKQ_THREAD_CREATED	0x00080000	/* a thread has been created */
9535a5a358SJonathan Adams #define	TASKQ_DUTY_CYCLE	0x00100000	/* using the SDC class */
967c478bd9Sstevel@tonic-gate 
977c478bd9Sstevel@tonic-gate struct taskq {
987c478bd9Sstevel@tonic-gate 	char		tq_name[TASKQ_NAMELEN + 1];
997c478bd9Sstevel@tonic-gate 	kmutex_t	tq_lock;
1007c478bd9Sstevel@tonic-gate 	krwlock_t	tq_threadlock;
1017c478bd9Sstevel@tonic-gate 	kcondvar_t	tq_dispatch_cv;
1027c478bd9Sstevel@tonic-gate 	kcondvar_t	tq_wait_cv;
1032e0c549eSJonathan Adams 	kcondvar_t	tq_exit_cv;
1042e0c549eSJonathan Adams 	pri_t		tq_pri;		/* Scheduling priority */
1057c478bd9Sstevel@tonic-gate 	uint_t		tq_flags;
1067c478bd9Sstevel@tonic-gate 	int		tq_active;
1077c478bd9Sstevel@tonic-gate 	int		tq_nthreads;
1082e0c549eSJonathan Adams 	int		tq_nthreads_target;
1092e0c549eSJonathan Adams 	int		tq_nthreads_max;
1102e0c549eSJonathan Adams 	int		tq_threads_ncpus_pct;
1117c478bd9Sstevel@tonic-gate 	int		tq_nalloc;
1127c478bd9Sstevel@tonic-gate 	int		tq_minalloc;
1137c478bd9Sstevel@tonic-gate 	int		tq_maxalloc;
114*64109744SChris Horne 	kcondvar_t	tq_maxalloc_cv;
115*64109744SChris Horne 	int		tq_maxalloc_wait;
1167c478bd9Sstevel@tonic-gate 	taskq_ent_t	*tq_freelist;
1177c478bd9Sstevel@tonic-gate 	taskq_ent_t	tq_task;
1187c478bd9Sstevel@tonic-gate 	int		tq_maxsize;
1197c478bd9Sstevel@tonic-gate 	taskq_bucket_t	*tq_buckets;	/* Per-cpu array of buckets */
1207c478bd9Sstevel@tonic-gate 	int		tq_instance;
1217c478bd9Sstevel@tonic-gate 	uint_t		tq_nbuckets;	/* # of buckets	(2^n)	    */
1227c478bd9Sstevel@tonic-gate 	union {
1237c478bd9Sstevel@tonic-gate 		kthread_t *_tq_thread;
1247c478bd9Sstevel@tonic-gate 		kthread_t **_tq_threadlist;
1257c478bd9Sstevel@tonic-gate 	}		tq_thr;
12635a5a358SJonathan Adams 
12735a5a358SJonathan Adams 	list_node_t	tq_cpupct_link;	/* linkage for taskq_cpupct_list */
12835a5a358SJonathan Adams 	struct proc	*tq_proc;	/* process for taskq threads */
12935a5a358SJonathan Adams 	int		tq_cpupart;	/* cpupart id bound to */
13035a5a358SJonathan Adams 	uint_t		tq_DC;		/* duty cycle for SDC */
13135a5a358SJonathan Adams 
1327c478bd9Sstevel@tonic-gate 	/*
1337c478bd9Sstevel@tonic-gate 	 * Statistics.
1347c478bd9Sstevel@tonic-gate 	 */
1357c478bd9Sstevel@tonic-gate 	kstat_t		*tq_kstat;	/* Exported statistics */
1367c478bd9Sstevel@tonic-gate 	hrtime_t	tq_totaltime;	/* Time spent processing tasks */
13735a5a358SJonathan Adams 	uint64_t	tq_tasks;	/* Total # of tasks posted */
13835a5a358SJonathan Adams 	uint64_t	tq_executed;	/* Total # of tasks executed */
1397c478bd9Sstevel@tonic-gate 	int		tq_maxtasks;	/* Max number of tasks in the queue */
1407c478bd9Sstevel@tonic-gate 	int		tq_tcreates;
1417c478bd9Sstevel@tonic-gate 	int		tq_tdeaths;
1427c478bd9Sstevel@tonic-gate };
1437c478bd9Sstevel@tonic-gate 
1447c478bd9Sstevel@tonic-gate #define	tq_thread tq_thr._tq_thread
1457c478bd9Sstevel@tonic-gate #define	tq_threadlist tq_thr._tq_threadlist
1467c478bd9Sstevel@tonic-gate 
1472e0c549eSJonathan Adams /* The MAX guarantees we have at least one thread */
1482e0c549eSJonathan Adams #define	TASKQ_THREADS_PCT(ncpus, pct)	MAX(((ncpus) * (pct)) / 100, 1)
1492e0c549eSJonathan Adams 
1507c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
1517c478bd9Sstevel@tonic-gate }
1527c478bd9Sstevel@tonic-gate #endif
1537c478bd9Sstevel@tonic-gate 
1547c478bd9Sstevel@tonic-gate #endif	/* _SYS_TASKQ_IMPL_H */
155