xref: /titanic_50/usr/src/uts/common/sys/taskq_impl.h (revision 5aeb94743e3be0c51e86f73096334611ae3a058e)
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 /*
2264109744SChris Horne  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  */
25*5aeb9474SGarrett D'Amore /*
26*5aeb9474SGarrett D'Amore  * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
27*5aeb9474SGarrett D'Amore  */
287c478bd9Sstevel@tonic-gate 
297c478bd9Sstevel@tonic-gate #ifndef	_SYS_TASKQ_IMPL_H
307c478bd9Sstevel@tonic-gate #define	_SYS_TASKQ_IMPL_H
317c478bd9Sstevel@tonic-gate 
327c478bd9Sstevel@tonic-gate #include <sys/taskq.h>
3335a5a358SJonathan Adams #include <sys/inttypes.h>
347c478bd9Sstevel@tonic-gate #include <sys/vmem.h>
3535a5a358SJonathan Adams #include <sys/list.h>
367c478bd9Sstevel@tonic-gate #include <sys/kstat.h>
377c478bd9Sstevel@tonic-gate 
387c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
397c478bd9Sstevel@tonic-gate extern "C" {
407c478bd9Sstevel@tonic-gate #endif
417c478bd9Sstevel@tonic-gate 
427c478bd9Sstevel@tonic-gate typedef struct taskq_bucket taskq_bucket_t;
437c478bd9Sstevel@tonic-gate 
447c478bd9Sstevel@tonic-gate typedef struct taskq_ent {
457c478bd9Sstevel@tonic-gate 	struct taskq_ent	*tqent_next;
467c478bd9Sstevel@tonic-gate 	struct taskq_ent	*tqent_prev;
477c478bd9Sstevel@tonic-gate 	task_func_t		*tqent_func;
487c478bd9Sstevel@tonic-gate 	void			*tqent_arg;
49*5aeb9474SGarrett D'Amore 	union {
507c478bd9Sstevel@tonic-gate 		taskq_bucket_t	*tqent_bucket;
51*5aeb9474SGarrett D'Amore 		uintptr_t	tqent_flags;
52*5aeb9474SGarrett D'Amore 	}			tqent_un;
537c478bd9Sstevel@tonic-gate 	kthread_t		*tqent_thread;
547c478bd9Sstevel@tonic-gate 	kcondvar_t		tqent_cv;
557c478bd9Sstevel@tonic-gate } taskq_ent_t;
567c478bd9Sstevel@tonic-gate 
57*5aeb9474SGarrett D'Amore #define	TQENT_FLAG_PREALLOC	0x1
58*5aeb9474SGarrett D'Amore 
597c478bd9Sstevel@tonic-gate /*
607c478bd9Sstevel@tonic-gate  * Taskq Statistics fields are not protected by any locks.
617c478bd9Sstevel@tonic-gate  */
627c478bd9Sstevel@tonic-gate typedef struct tqstat {
637c478bd9Sstevel@tonic-gate 	uint_t		tqs_hits;
647c478bd9Sstevel@tonic-gate 	uint_t		tqs_misses;
657c478bd9Sstevel@tonic-gate 	uint_t		tqs_overflow;	/* no threads to allocate   */
667c478bd9Sstevel@tonic-gate 	uint_t		tqs_tcreates;	/* threads created 	*/
677c478bd9Sstevel@tonic-gate 	uint_t		tqs_tdeaths;	/* threads died		*/
687c478bd9Sstevel@tonic-gate 	uint_t		tqs_maxthreads;	/* max # of alive threads */
697c478bd9Sstevel@tonic-gate 	uint_t		tqs_nomem;	/* # of times there were no memory */
707c478bd9Sstevel@tonic-gate 	uint_t		tqs_disptcreates;
717c478bd9Sstevel@tonic-gate } tqstat_t;
727c478bd9Sstevel@tonic-gate 
737c478bd9Sstevel@tonic-gate /*
747c478bd9Sstevel@tonic-gate  * Per-CPU hash bucket manages taskq_bent_t structures using freelist.
757c478bd9Sstevel@tonic-gate  */
767c478bd9Sstevel@tonic-gate struct taskq_bucket {
777c478bd9Sstevel@tonic-gate 	kmutex_t	tqbucket_lock;
787c478bd9Sstevel@tonic-gate 	taskq_t		*tqbucket_taskq;	/* Enclosing taskq */
797c478bd9Sstevel@tonic-gate 	taskq_ent_t	tqbucket_freelist;
807c478bd9Sstevel@tonic-gate 	uint_t		tqbucket_nalloc;	/* # of allocated entries */
817c478bd9Sstevel@tonic-gate 	uint_t		tqbucket_nfree;		/* # of free entries */
827c478bd9Sstevel@tonic-gate 	kcondvar_t	tqbucket_cv;
837c478bd9Sstevel@tonic-gate 	ushort_t	tqbucket_flags;
847c478bd9Sstevel@tonic-gate 	hrtime_t	tqbucket_totaltime;
857c478bd9Sstevel@tonic-gate 	tqstat_t	tqbucket_stat;
867c478bd9Sstevel@tonic-gate };
877c478bd9Sstevel@tonic-gate 
887c478bd9Sstevel@tonic-gate /*
897c478bd9Sstevel@tonic-gate  * Bucket flags.
907c478bd9Sstevel@tonic-gate  */
917c478bd9Sstevel@tonic-gate #define	TQBUCKET_CLOSE		0x01
927c478bd9Sstevel@tonic-gate #define	TQBUCKET_SUSPEND	0x02
937c478bd9Sstevel@tonic-gate 
9435a5a358SJonathan Adams #define	TASKQ_INTERFACE_FLAGS	0x0000ffff	/* defined in <sys/taskq.h> */
9535a5a358SJonathan Adams 
967c478bd9Sstevel@tonic-gate /*
977c478bd9Sstevel@tonic-gate  * taskq implementation flags: bit range 16-31
987c478bd9Sstevel@tonic-gate  */
9935a5a358SJonathan Adams #define	TASKQ_CHANGING		0x00010000	/* nthreads != target */
10035a5a358SJonathan Adams #define	TASKQ_SUSPENDED		0x00020000	/* taskq is suspended */
10135a5a358SJonathan Adams #define	TASKQ_NOINSTANCE	0x00040000	/* no instance number */
10235a5a358SJonathan Adams #define	TASKQ_THREAD_CREATED	0x00080000	/* a thread has been created */
10335a5a358SJonathan Adams #define	TASKQ_DUTY_CYCLE	0x00100000	/* using the SDC class */
1047c478bd9Sstevel@tonic-gate 
1057c478bd9Sstevel@tonic-gate struct taskq {
1067c478bd9Sstevel@tonic-gate 	char		tq_name[TASKQ_NAMELEN + 1];
1077c478bd9Sstevel@tonic-gate 	kmutex_t	tq_lock;
1087c478bd9Sstevel@tonic-gate 	krwlock_t	tq_threadlock;
1097c478bd9Sstevel@tonic-gate 	kcondvar_t	tq_dispatch_cv;
1107c478bd9Sstevel@tonic-gate 	kcondvar_t	tq_wait_cv;
1112e0c549eSJonathan Adams 	kcondvar_t	tq_exit_cv;
1122e0c549eSJonathan Adams 	pri_t		tq_pri;		/* Scheduling priority */
1137c478bd9Sstevel@tonic-gate 	uint_t		tq_flags;
1147c478bd9Sstevel@tonic-gate 	int		tq_active;
1157c478bd9Sstevel@tonic-gate 	int		tq_nthreads;
1162e0c549eSJonathan Adams 	int		tq_nthreads_target;
1172e0c549eSJonathan Adams 	int		tq_nthreads_max;
1182e0c549eSJonathan Adams 	int		tq_threads_ncpus_pct;
1197c478bd9Sstevel@tonic-gate 	int		tq_nalloc;
1207c478bd9Sstevel@tonic-gate 	int		tq_minalloc;
1217c478bd9Sstevel@tonic-gate 	int		tq_maxalloc;
12264109744SChris Horne 	kcondvar_t	tq_maxalloc_cv;
12364109744SChris Horne 	int		tq_maxalloc_wait;
1247c478bd9Sstevel@tonic-gate 	taskq_ent_t	*tq_freelist;
1257c478bd9Sstevel@tonic-gate 	taskq_ent_t	tq_task;
1267c478bd9Sstevel@tonic-gate 	int		tq_maxsize;
1277c478bd9Sstevel@tonic-gate 	taskq_bucket_t	*tq_buckets;	/* Per-cpu array of buckets */
1287c478bd9Sstevel@tonic-gate 	int		tq_instance;
1297c478bd9Sstevel@tonic-gate 	uint_t		tq_nbuckets;	/* # of buckets	(2^n)	    */
1307c478bd9Sstevel@tonic-gate 	union {
1317c478bd9Sstevel@tonic-gate 		kthread_t *_tq_thread;
1327c478bd9Sstevel@tonic-gate 		kthread_t **_tq_threadlist;
1337c478bd9Sstevel@tonic-gate 	}		tq_thr;
13435a5a358SJonathan Adams 
13535a5a358SJonathan Adams 	list_node_t	tq_cpupct_link;	/* linkage for taskq_cpupct_list */
13635a5a358SJonathan Adams 	struct proc	*tq_proc;	/* process for taskq threads */
13735a5a358SJonathan Adams 	int		tq_cpupart;	/* cpupart id bound to */
13835a5a358SJonathan Adams 	uint_t		tq_DC;		/* duty cycle for SDC */
13935a5a358SJonathan Adams 
1407c478bd9Sstevel@tonic-gate 	/*
1417c478bd9Sstevel@tonic-gate 	 * Statistics.
1427c478bd9Sstevel@tonic-gate 	 */
1437c478bd9Sstevel@tonic-gate 	kstat_t		*tq_kstat;	/* Exported statistics */
1447c478bd9Sstevel@tonic-gate 	hrtime_t	tq_totaltime;	/* Time spent processing tasks */
14535a5a358SJonathan Adams 	uint64_t	tq_tasks;	/* Total # of tasks posted */
14635a5a358SJonathan Adams 	uint64_t	tq_executed;	/* Total # of tasks executed */
1477c478bd9Sstevel@tonic-gate 	int		tq_maxtasks;	/* Max number of tasks in the queue */
1487c478bd9Sstevel@tonic-gate 	int		tq_tcreates;
1497c478bd9Sstevel@tonic-gate 	int		tq_tdeaths;
1507c478bd9Sstevel@tonic-gate };
1517c478bd9Sstevel@tonic-gate 
152*5aeb9474SGarrett D'Amore /* Special form of taskq dispatch that uses preallocated entries. */
153*5aeb9474SGarrett D'Amore void taskq_dispatch_ent(taskq_t *, task_func_t, void *, uint_t, taskq_ent_t *);
154*5aeb9474SGarrett D'Amore 
155*5aeb9474SGarrett D'Amore 
1567c478bd9Sstevel@tonic-gate #define	tq_thread tq_thr._tq_thread
1577c478bd9Sstevel@tonic-gate #define	tq_threadlist tq_thr._tq_threadlist
1587c478bd9Sstevel@tonic-gate 
1592e0c549eSJonathan Adams /* The MAX guarantees we have at least one thread */
1602e0c549eSJonathan Adams #define	TASKQ_THREADS_PCT(ncpus, pct)	MAX(((ncpus) * (pct)) / 100, 1)
1612e0c549eSJonathan Adams 
1627c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
1637c478bd9Sstevel@tonic-gate }
1647c478bd9Sstevel@tonic-gate #endif
1657c478bd9Sstevel@tonic-gate 
1667c478bd9Sstevel@tonic-gate #endif	/* _SYS_TASKQ_IMPL_H */
167