1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
|
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _CHIP_H
#define _CHIP_H
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* generic kernel CMT processor support
*/
#ifdef __cplusplus
extern "C" {
#endif
#if (defined(_KERNEL) || defined(_KMEMUSER))
#include <sys/cpuvar.h>
#include <sys/processor.h>
#include <sys/bitmap.h>
#include <sys/atomic.h>
#include <sys/types.h>
/*
* Chip types
*/
typedef enum chip_type {
CHIP_DEFAULT, /* Default, non CMT processor */
CHIP_SMT, /* SMT, single core */
CHIP_CMP_SPLIT_CACHE, /* CMP with split caches */
CHIP_CMP_SHARED_CACHE, /* CMP with shared caches */
CHIP_NUM_TYPES
} chip_type_t;
/*
* Balancing is possible if multiple chips exist in the lgroup
* but only necessary if the chip has multiple online logical CPUs
*/
#define CHIP_SHOULD_BALANCE(chp) \
(((chp)->chip_ncpu > 1) && ((chp)->chip_next_lgrp != (chp)))
/*
* Platform's definition of a chip's properties
*/
typedef struct chip_def {
chip_type_t chipd_type;
int chipd_rechoose_adj;
} chip_def_t;
/*
* Per chip kstats
*/
typedef enum chip_stat_types {
CHIP_ID, /* chip "id" */
CHIP_NCPUS, /* number of active cpus */
CHIP_NRUNNING, /* number of running threads on chip */
CHIP_RECHOOSE, /* chip's rechoose_interval */
CHIP_NUM_STATS /* always last */
} chip_stat_t;
#define CHIP_KSTAT_NAMES \
static char *chip_kstat_names[] = { \
\
"chip_id", \
"logical_cpus", \
"chip_nrunning", \
"chip_rechoose_interval", \
}
/*
* Physical processor (chip) structure.
*/
typedef struct chip {
chipid_t chip_id; /* chip's "id" */
chipid_t chip_seqid; /* sequential id */
struct chip *chip_prev; /* previous chip on list */
struct chip *chip_next; /* next chip on list */
struct chip *chip_prev_lgrp; /* prev chip in lgroup */
struct chip *chip_next_lgrp; /* next chip in lgroup */
chip_type_t chip_type; /* type of chip */
uint16_t chip_ncpu; /* number of active cpus */
uint16_t chip_ref; /* chip's reference count */
struct cpu *chip_cpus; /* per chip cpu list */
struct lgrp *chip_lgrp; /* chip lives in this lgroup */
int chip_rechoose_adj; /* chip specific adjustment */
/*
* chip kstats
*/
kstat_t *chip_kstat;
kmutex_t chip_kstat_mutex;
struct kstat_named chip_kstat_data[CHIP_NUM_STATS];
struct chip *chip_balance; /* chip to balance against */
uint32_t chip_nrunning; /* # of running threads */
} chip_t;
/*
* Change the number of running threads on the chip
*/
#define CHIP_NRUNNING(chp, n) { \
atomic_add_32(&((chp)->chip_nrunning), (n)); \
}
/*
* True if this CPU is active on the chip
*/
#define CHIP_CPU_ACTIVE(cp) ((cp)->cpu_next_chip != NULL)
/*
* Sets of chips
* The "id" used here should be a chip's sequential id.
* (chip_seqid)
*/
#if defined(_MACHDEP)
#define CHIP_MAX_CHIPS NCPU
#define CHIP_SET_WORDS BT_BITOUL(CHIP_MAX_CHIPS)
typedef struct chip_set {
ulong_t csb[CHIP_SET_WORDS];
} chip_set_t;
extern int chip_set_isnull(chip_set_t *);
#define CHIP_SET_ISNULL(set) chip_set_isnull(&(set))
#define CHIP_SET_TEST(set, id) BT_TEST((set).csb, id)
#define CHIP_SET_REMOVE(set, id) BT_CLEAR((set).csb, id)
#define CHIP_SET_ADD(set, id) BT_SET((set).csb, id)
#define CHIP_SET_ZERO(set) { \
int _i; \
for (_i = 0; _i < CHIP_SET_WORDS; _i++) \
(set).csb[_i] = 0; \
}
#define CHIP_IN_CPUPART(chp, cp) \
(CHIP_SET_TEST((cp)->cp_chipset, (chp)->chip_seqid))
#endif /* _MACHDEP */
/*
* Common kernel chip operations
*/
void chip_cpu_init(cpu_t *);
void chip_cpu_fini(cpu_t *);
void chip_cpu_assign(cpu_t *);
void chip_cpu_unassign(cpu_t *);
void chip_cpu_startup(cpu_t *);
void chip_bootstrap_cpu(cpu_t *);
void chip_cpu_move_part(cpu_t *, struct cpupart *,
struct cpupart *);
void chip_kstat_create(chip_t *);
/*
* Platform chip operations
*/
chipid_t chip_plat_get_chipid(cpu_t *);
#ifdef sun4v
id_t chip_plat_get_pipeid(cpu_t *);
#endif /* sun4v */
void chip_plat_define_chip(cpu_t *, chip_def_t *);
int chip_plat_get_clogid(cpu_t *);
#endif /* !_KERNEL && !_KMEMUSER */
#ifdef __cplusplus
}
#endif
#endif /* _CHIP_H */
|