xref: /onnv-gate/usr/src/cmd/rcap/common/rcapd.h (revision 4119:293019c5ea1f)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
53247Sgjelinek  * Common Development and Distribution License (the "License").
63247Sgjelinek  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
210Sstevel@tonic-gate /*
22*4119Stn143363  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
230Sstevel@tonic-gate  * Use is subject to license terms.
240Sstevel@tonic-gate  */
250Sstevel@tonic-gate 
260Sstevel@tonic-gate #ifndef _RCAPD_H
270Sstevel@tonic-gate #define	_RCAPD_H
280Sstevel@tonic-gate 
290Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
300Sstevel@tonic-gate 
310Sstevel@tonic-gate #ifdef	__cplusplus
320Sstevel@tonic-gate extern "C" {
330Sstevel@tonic-gate #endif
340Sstevel@tonic-gate 
350Sstevel@tonic-gate #include <sys/types.h>
360Sstevel@tonic-gate #include <procfs.h>
370Sstevel@tonic-gate #include "rcapd_conf.h"
380Sstevel@tonic-gate 
390Sstevel@tonic-gate #define	LC_NAME_LEN			32
40*4119Stn143363 #define	RCAP_FMRI			"svc:/system/rcap:default"
41*4119Stn143363 #define	CONFIG_PG			"config"
42*4119Stn143363 #define	PRESSURE			"pressure"
43*4119Stn143363 #define	RECONFIG_INT			"reconfig_interval"
44*4119Stn143363 #define	REPORT_INT			"report_interval"
45*4119Stn143363 #define	RSS_SAMPLE_INT			"rss_sample_interval"
46*4119Stn143363 #define	WALK_INT			"walk_interval"
470Sstevel@tonic-gate #define	RCAPD_IGNORED_SET_FLUSH_IVAL	10	/* number of scans between */
480Sstevel@tonic-gate 						/* flushes of the ignored set */
490Sstevel@tonic-gate 
500Sstevel@tonic-gate /*
510Sstevel@tonic-gate  * set the buffer length for /proc-based path names based on the actual
520Sstevel@tonic-gate  * length of the largest pid
530Sstevel@tonic-gate  */
540Sstevel@tonic-gate #define	RCAPD__STR(a)		#a
550Sstevel@tonic-gate #define	RCAPD_STR(macro)	RCAPD__STR(macro)
560Sstevel@tonic-gate #define	PROC_PATH_MAX		(sizeof ("/proc/" RCAPD_STR(PID_MAX) \
570Sstevel@tonic-gate 				    "/pagedata"))
580Sstevel@tonic-gate 
590Sstevel@tonic-gate /*
600Sstevel@tonic-gate  * lcollection_insert_update() result flags
610Sstevel@tonic-gate  */
620Sstevel@tonic-gate #define	LCST_CAP_CHANGED		(1<<0)
630Sstevel@tonic-gate #define	LCST_CAP_REMOVED		(1<<1)
640Sstevel@tonic-gate #define	LCST_CAP_ZERO			(1<<2)
650Sstevel@tonic-gate 
663247Sgjelinek typedef enum {
673247Sgjelinek 	RCIDT_PROJECT,
683247Sgjelinek 	RCIDT_ZONE
693247Sgjelinek } rcid_type_t;
703247Sgjelinek 
713247Sgjelinek typedef struct {
723247Sgjelinek 	/*
733247Sgjelinek 	 * The following field could just be a rcid_type_t but it gets
743247Sgjelinek 	 * written out to a file as binary data for communication between
753247Sgjelinek 	 * 64-bit rcapd & 32-bit rcapstat, so we need to force a standard size
763247Sgjelinek 	 * and alignment here.
773247Sgjelinek 	 */
783247Sgjelinek 	uint64_t	rcid_type;
793247Sgjelinek 	int64_t		rcid_val;
803247Sgjelinek } rcid_t;
810Sstevel@tonic-gate 
820Sstevel@tonic-gate typedef enum {
830Sstevel@tonic-gate 	LCU_COMPLETE,	/* an enumeration of all possible collections */
840Sstevel@tonic-gate 	LCU_ACTIVE_ONLY	/* an enumeration of only once-active collections */
850Sstevel@tonic-gate } lcollection_update_type_t;
860Sstevel@tonic-gate 
870Sstevel@tonic-gate struct lmapping;
880Sstevel@tonic-gate struct lprocess;
890Sstevel@tonic-gate struct lcollection;
900Sstevel@tonic-gate struct prxmap;
910Sstevel@tonic-gate struct psinfo;
920Sstevel@tonic-gate 
930Sstevel@tonic-gate /*
940Sstevel@tonic-gate  * Per-process data.
950Sstevel@tonic-gate  */
960Sstevel@tonic-gate typedef struct lprocess {
970Sstevel@tonic-gate 	struct lprocess *lpc_prev;	/* global process list */
980Sstevel@tonic-gate 	struct lprocess *lpc_next;
990Sstevel@tonic-gate 
1000Sstevel@tonic-gate 	pid_t		lpc_pid;	/* ID of this process */
1010Sstevel@tonic-gate 	int		lpc_unscannable; /* flag indicating zombie or */
1020Sstevel@tonic-gate 					/* other unscannable process */
1030Sstevel@tonic-gate 	uint64_t	lpc_rss;	/* resident set size (kB) */
1040Sstevel@tonic-gate 	uint64_t	lpc_unrm;	/* scannable set size (kB) (est.) */
1050Sstevel@tonic-gate 	uint64_t	lpc_size;	/* process image size (kB) */
1060Sstevel@tonic-gate 	int		lpc_mark;	/* mark-and-sweep flag */
1070Sstevel@tonic-gate 	struct lcollection *lpc_collection; /* owning collection */
1080Sstevel@tonic-gate 	int		lpc_psinfo_fd;	/* cached psinfo fd */
1090Sstevel@tonic-gate 	int		lpc_pgdata_fd;	/* cached pagedata fd */
1100Sstevel@tonic-gate 	int		lpc_xmap_fd;	/* cached xmap fd */
1110Sstevel@tonic-gate 	struct prxmap	*lpc_xmap;	/* xmap corresponding to */
1120Sstevel@tonic-gate 					/* current pagedata */
1130Sstevel@tonic-gate 	int		lpc_nxmap;	/* number of mappings in xmap */
1140Sstevel@tonic-gate 	prpageheader_t *lpc_prpageheader; /* accumulated mask of */
1150Sstevel@tonic-gate 					/* process's ref/mod bits */
1160Sstevel@tonic-gate 	struct lmapping	*lpc_ignore;	/* empirically-unpageable mappings */
1170Sstevel@tonic-gate } lprocess_t;
1180Sstevel@tonic-gate 
1190Sstevel@tonic-gate /*
1200Sstevel@tonic-gate  * Collection statistics.
1210Sstevel@tonic-gate  */
1220Sstevel@tonic-gate typedef struct {
1230Sstevel@tonic-gate 	uint64_t lcols_scan;		/* scan attempts */
1240Sstevel@tonic-gate 	uint64_t lcols_pg_att;		/* kB attempted to page */
1250Sstevel@tonic-gate 	uint64_t lcols_pg_eff;		/* kB paged out (est.) */
1260Sstevel@tonic-gate 	uint64_t lcols_rss_sample;	/* RSS samplings */
1270Sstevel@tonic-gate 	uint64_t lcols_unenforced_cap;	/* times cap could have been */
1280Sstevel@tonic-gate 					/* enforced, but wasn't (due to low */
1290Sstevel@tonic-gate 					/* global memory pressure, or global */
1300Sstevel@tonic-gate 					/* scanner being activated) */
1310Sstevel@tonic-gate 	uint64_t lcols_rss_sum;		/* sum of sampled RSS values */
1320Sstevel@tonic-gate 	uint64_t lcols_rss_act_sum;	/* sum of sampled, excess RSS values */
1330Sstevel@tonic-gate 	uint64_t lcols_min_rss;		/* minimum RSS (kB), this interval */
1340Sstevel@tonic-gate 	uint64_t lcols_max_rss;		/* maximum RSS (kB), this interval */
1350Sstevel@tonic-gate 	uint64_t lcols_proc_in;		/* processes tracked */
1360Sstevel@tonic-gate 	uint64_t lcols_proc_out;	/* processes freed */
1370Sstevel@tonic-gate 	hrtime_t lcols_scan_time;	/* time spent scanning (ns) */
1380Sstevel@tonic-gate 	hrtime_t lcols_scan_time_complete; /* time spent scanning (ns) */
1390Sstevel@tonic-gate 					/* at last completion */
1400Sstevel@tonic-gate 	uint64_t lcols_scan_count;	/* number of complete scans */
1410Sstevel@tonic-gate 	uint64_t lcols_scan_ineffective; /* number of uninterrupted */
1420Sstevel@tonic-gate 					/* revolutions of clock hand after */
1430Sstevel@tonic-gate 					/* which the excess was not */
1440Sstevel@tonic-gate 					/* completely reduced */
1450Sstevel@tonic-gate } lcollection_stat_t;
1460Sstevel@tonic-gate 
1470Sstevel@tonic-gate /*
1480Sstevel@tonic-gate  * Collection.
1490Sstevel@tonic-gate  */
1500Sstevel@tonic-gate typedef struct lcollection {
1510Sstevel@tonic-gate 	struct lcollection *lcol_prev;	/* global collection list */
1520Sstevel@tonic-gate 	struct lcollection *lcol_next;
1530Sstevel@tonic-gate 
1540Sstevel@tonic-gate 	rcid_t lcol_id;			/* numerical ID for this collection */
1550Sstevel@tonic-gate 	char lcol_name[LC_NAME_LEN];	/* name of this collection, or */
1560Sstevel@tonic-gate 					/* "unknown" */
1570Sstevel@tonic-gate 	uint64_t lcol_rss;		/* RSS of all processes (kB) */
1580Sstevel@tonic-gate 	uint64_t lcol_image_size;	/* image size of all processes (kB) */
1590Sstevel@tonic-gate 	uint64_t lcol_rss_cap;		/* RSS cap (kB) */
1600Sstevel@tonic-gate 	lcollection_stat_t lcol_stat;	/* statistics */
1610Sstevel@tonic-gate 	lcollection_stat_t lcol_stat_old; /* previous interval's statistics */
1620Sstevel@tonic-gate 	lprocess_t *lcol_lprocess;	/* member processes */
1630Sstevel@tonic-gate 	int lcol_mark;			/* mark-and-sweep flag */
1640Sstevel@tonic-gate 	lprocess_t *lcol_victim;	/* victim process to resume scanning */
1650Sstevel@tonic-gate 	void *lcol_resaddr;		/* address to resume scanning from */
1660Sstevel@tonic-gate } lcollection_t;
1670Sstevel@tonic-gate 
1680Sstevel@tonic-gate /*
1690Sstevel@tonic-gate  * Collection report.
1700Sstevel@tonic-gate  */
1710Sstevel@tonic-gate typedef struct lcollection_report {
1720Sstevel@tonic-gate 	rcid_t lcol_id;			/* numerical ID for this collection */
1730Sstevel@tonic-gate 	char lcol_name[LC_NAME_LEN];	/* name of this collection, or */
1740Sstevel@tonic-gate 					/* "unknown" */
1750Sstevel@tonic-gate 	uint64_t lcol_rss;		/* RSS of all processes (kB) */
1760Sstevel@tonic-gate 	uint64_t lcol_image_size;	/* image size of all processes (kB) */
1770Sstevel@tonic-gate 	uint64_t lcol_rss_cap;		/* RSS limit (kB) */
1780Sstevel@tonic-gate 	lcollection_stat_t lcol_stat;	/* statistics */
1790Sstevel@tonic-gate } lcollection_report_t;
1800Sstevel@tonic-gate 
1810Sstevel@tonic-gate extern int get_psinfo(pid_t, struct psinfo *, int, int(*)(void *, int), void *,
1820Sstevel@tonic-gate     lprocess_t *);
1833247Sgjelinek extern lcollection_t *lcollection_find(rcid_t *);
1840Sstevel@tonic-gate extern void lcollection_freq_move(lprocess_t *);
1853247Sgjelinek extern lcollection_t *lcollection_insert_update(rcid_t *, uint64_t, char *,
1860Sstevel@tonic-gate     int *changes);
1870Sstevel@tonic-gate extern int lcollection_member(lcollection_t *, lprocess_t *);
1880Sstevel@tonic-gate extern void lcollection_free(lcollection_t *);
1890Sstevel@tonic-gate extern void lcollection_update(lcollection_update_type_t);
1900Sstevel@tonic-gate extern void list_walk_collection(int (*)(lcollection_t *, void *), void *);
1910Sstevel@tonic-gate extern int lprocess_update_psinfo_fd_cb(void *, int);
1920Sstevel@tonic-gate extern void lprocess_free(lprocess_t *);
1930Sstevel@tonic-gate extern void scan(lcollection_t *, int64_t);
1940Sstevel@tonic-gate extern void scan_abort(void);
1950Sstevel@tonic-gate extern void check_update_statistics(void);
1960Sstevel@tonic-gate 
1970Sstevel@tonic-gate /*
1980Sstevel@tonic-gate  * Global (in rcapd only) variables.
1990Sstevel@tonic-gate  */
2000Sstevel@tonic-gate extern rcfg_t rcfg;
2010Sstevel@tonic-gate extern uint64_t phys_total;
2020Sstevel@tonic-gate extern int should_run;
2030Sstevel@tonic-gate 
2040Sstevel@tonic-gate #ifdef	__cplusplus
2050Sstevel@tonic-gate }
2060Sstevel@tonic-gate #endif
2070Sstevel@tonic-gate 
2080Sstevel@tonic-gate #endif /* _RCAPD_H */
209