[CLASSES]: Find bit holes
An example is worth a thousand words, look for "XXX ... bit hole, try to pack" and the stats at the bottom: [acme@newtoy net-2.6]$ pahole ../OUTPUT/qemu/net-2.6/fs/inode.o task_struct /* include2/asm/system.h:11 */ struct task_struct { volatile long int state; /* 0 4 */ struct thread_info * thread_info; /* 4 4 */ atomic_t usage; /* 8 4 */ long unsigned int flags; /* 12 4 */ long unsigned int ptrace; /* 16 4 */ int lock_depth; /* 20 4 */ int load_weight; /* 24 4 */ int prio; /* 28 4 */ /* --- cacheline 1 boundary (32 bytes) --- */ int static_prio; /* 32 4 */ int normal_prio; /* 36 4 */ struct list_head run_list; /* 40 8 */ struct prio_array * array; /* 48 4 */ short unsigned int ioprio; /* 52 2 */ /* XXX 2 bytes hole, try to pack */ long unsigned int sleep_avg; /* 56 4 */ long long unsigned int timestamp; /* 60 8 */ /* --- cacheline 2 boundary (64 bytes) was 4 bytes ago --- */ long long unsigned int last_ran; /* 68 8 */ long long unsigned int sched_time; /* 76 8 */ enum sleep_type sleep_type; /* 84 4 */ long unsigned int policy; /* 88 4 */ cpumask_t cpus_allowed; /* 92 4 */ /* --- cacheline 3 boundary (96 bytes) --- */ unsigned int time_slice; /* 96 4 */ unsigned int first_time_slice; /* 100 4 */ struct list_head tasks; /* 104 8 */ struct list_head ptrace_children; /* 112 8 */ struct list_head ptrace_list; /* 120 8 */ /* --- cacheline 4 boundary (128 bytes) --- */ struct mm_struct * mm; /* 128 4 */ struct mm_struct * active_mm; /* 132 4 */ struct linux_binfmt * binfmt; /* 136 4 */ long int exit_state; /* 140 4 */ int exit_code; /* 144 4 */ int exit_signal; /* 148 4 */ int pdeath_signal; /* 152 4 */ long unsigned int personality; /* 156 4 */ /* --- cacheline 5 boundary (160 bytes) --- */ unsigned int did_exec:1; /* 160 4 */ /* XXX 31 bits hole, try to pack */ pid_t pid; /* 164 4 */ pid_t tgid; /* 168 4 */ struct task_struct * real_parent; /* 172 4 */ struct task_struct * parent; /* 176 4 */ struct list_head children; /* 180 8 */ struct list_head sibling; /* 188 8 */ /* --- cacheline 6 boundary (192 bytes) was 4 bytes ago --- */ struct task_struct * group_leader; /* 196 4 */ struct pid_link pids[3]; /* 200 36 */ /* --- cacheline 7 boundary (224 bytes) was 12 bytes ago --- */ struct list_head thread_group; /* 236 8 */ struct completion * vfork_done; /* 244 4 */ int * set_child_tid; /* 248 4 */ int * clear_child_tid; /* 252 4 */ /* --- cacheline 8 boundary (256 bytes) --- */ long unsigned int rt_priority; /* 256 4 */ cputime_t utime; /* 260 4 */ cputime_t stime; /* 264 4 */ long unsigned int nvcsw; /* 268 4 */ long unsigned int nivcsw; /* 272 4 */ struct timespec start_time; /* 276 8 */ long unsigned int min_flt; /* 284 4 */ /* --- cacheline 9 boundary (288 bytes) --- */ long unsigned int maj_flt; /* 288 4 */ cputime_t it_prof_expires; /* 292 4 */ cputime_t it_virt_expires; /* 296 4 */ long long unsigned int it_sched_expires; /* 300 8 */ struct list_head cpu_timers[3]; /* 308 24 */ /* --- cacheline 10 boundary (320 bytes) was 12 bytes ago --- */ uid_t uid; /* 332 4 */ uid_t euid; /* 336 4 */ uid_t suid; /* 340 4 */ uid_t fsuid; /* 344 4 */ gid_t gid; /* 348 4 */ /* --- cacheline 11 boundary (352 bytes) --- */ gid_t egid; /* 352 4 */ gid_t sgid; /* 356 4 */ gid_t fsgid; /* 360 4 */ struct group_info * group_info; /* 364 4 */ kernel_cap_t cap_effective; /* 368 4 */ kernel_cap_t cap_inheritable; /* 372 4 */ kernel_cap_t cap_permitted; /* 376 4 */ unsigned int keep_capabilities:1; /* 380 4 */ /* XXX 31 bits hole, try to pack */ /* --- cacheline 12 boundary (384 bytes) --- */ struct user_struct * user; /* 384 4 */ struct key * request_key_auth; /* 388 4 */ struct key * thread_keyring; /* 392 4 */ unsigned char jit_keyring; /* 396 1 */ unsigned char fpu_counter; /* 397 1 */ /* XXX 2 bytes hole, try to pack */ int oomkilladj; /* 400 4 */ char comm[16]; /* 404 16 */ /* --- cacheline 13 boundary (416 bytes) was 4 bytes ago --- */ int link_count; /* 420 4 */ int total_link_count; /* 424 4 */ struct sysv_sem sysvsem; /* 428 4 */ struct thread_struct thread; /* 432 656 */ /* --- cacheline 34 boundary (1088 bytes) --- */ struct fs_struct * fs; /* 1088 4 */ struct files_struct * files; /* 1092 4 */ struct nsproxy * nsproxy; /* 1096 4 */ struct signal_struct * signal; /* 1100 4 */ struct sighand_struct * sighand; /* 1104 4 */ sigset_t blocked; /* 1108 8 */ sigset_t real_blocked; /* 1116 8 */ /* --- cacheline 35 boundary (1120 bytes) was 4 bytes ago --- */ sigset_t saved_sigmask; /* 1124 8 */ struct sigpending pending; /* 1132 16 */ long unsigned int sas_ss_sp; /* 1148 4 */ /* --- cacheline 36 boundary (1152 bytes) --- */ size_t sas_ss_size; /* 1152 4 */ int (*notifier)(); /* 1156 4 */ void * notifier_data; /* 1160 4 */ sigset_t * notifier_mask; /* 1164 4 */ void * security; /* 1168 4 */ struct audit_context * audit_context; /* 1172 4 */ seccomp_t seccomp; /* 1176 0 */ u32 parent_exec_id; /* 1176 4 */ u32 self_exec_id; /* 1180 4 */ /* --- cacheline 37 boundary (1184 bytes) --- */ spinlock_t alloc_lock; /* 1184 40 */ /* --- cacheline 38 boundary (1216 bytes) was 8 bytes ago --- */ spinlock_t pi_lock; /* 1224 40 */ /* --- cacheline 39 boundary (1248 bytes) was 16 bytes ago --- */ struct plist_head pi_waiters; /* 1264 20 */ /* --- cacheline 40 boundary (1280 bytes) was 4 bytes ago --- */ struct rt_mutex_waiter * pi_blocked_on; /* 1284 4 */ struct mutex_waiter * blocked_on; /* 1288 4 */ unsigned int irq_events; /* 1292 4 */ int hardirqs_enabled; /* 1296 4 */ long unsigned int hardirq_enable_ip; /* 1300 4 */ unsigned int hardirq_enable_event; /* 1304 4 */ long unsigned int hardirq_disable_ip; /* 1308 4 */ /* --- cacheline 41 boundary (1312 bytes) --- */ unsigned int hardirq_disable_event; /* 1312 4 */ int softirqs_enabled; /* 1316 4 */ long unsigned int softirq_disable_ip; /* 1320 4 */ unsigned int softirq_disable_event; /* 1324 4 */ long unsigned int softirq_enable_ip; /* 1328 4 */ unsigned int softirq_enable_event; /* 1332 4 */ int hardirq_context; /* 1336 4 */ int softirq_context; /* 1340 4 */ /* --- cacheline 42 boundary (1344 bytes) --- */ u64 curr_chain_key; /* 1344 8 */ int lockdep_depth; /* 1352 4 */ struct held_lock held_locks[30]; /* 1356 1200 */ /* --- cacheline 79 boundary (2528 bytes) was 28 bytes ago --- */ unsigned int lockdep_recursion; /* 2556 4 */ /* --- cacheline 80 boundary (2560 bytes) --- */ void * journal_info; /* 2560 4 */ struct reclaim_state * reclaim_state; /* 2564 4 */ struct backing_dev_info * backing_dev_info; /* 2568 4 */ struct io_context * io_context; /* 2572 4 */ long unsigned int ptrace_message; /* 2576 4 */ siginfo_t * last_siginfo; /* 2580 4 */ wait_queue_t * io_wait; /* 2584 4 */ u64 rchar; /* 2588 8 */ /* --- cacheline 81 boundary (2592 bytes) was 4 bytes ago --- */ u64 wchar; /* 2596 8 */ u64 syscr; /* 2604 8 */ u64 syscw; /* 2612 8 */ struct robust_list_head * robust_list; /* 2620 4 */ /* --- cacheline 82 boundary (2624 bytes) --- */ struct list_head pi_state_list; /* 2624 8 */ struct futex_pi_state * pi_state_cache; /* 2632 4 */ atomic_t fs_excl; /* 2636 4 */ struct rcu_head rcu; /* 2640 8 */ struct pipe_inode_info * splice_pipe; /* 2648 4 */ }; /* size: 2656, cachelines: 83 */ /* sum members: 2648, holes: 2, sum holes: 4 */ /* bit holes: 2, sum bit holes: 62 bits */ /* padding: 4 */ Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
This commit is contained in:
parent
fb4fed3164
commit
a373c28ba9
45
classes.c
45
classes.c
|
@ -658,6 +658,7 @@ void class__find_holes(struct class *self)
|
|||
{
|
||||
struct class_member *pos, *last = NULL;
|
||||
uint64_t last_size = 0, size;
|
||||
unsigned int bit_sum = 0;
|
||||
|
||||
self->nr_holes = 0;
|
||||
|
||||
|
@ -676,8 +677,21 @@ void class__find_holes(struct class *self)
|
|||
if (last->hole > 0)
|
||||
++self->nr_holes;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (pos->bit_size == 0) {
|
||||
if (bit_sum != 0) {
|
||||
last->bit_hole = (last_size * 8) - bit_sum;
|
||||
|
||||
if (last->bit_hole != 0)
|
||||
++self->nr_bit_holes;
|
||||
|
||||
bit_sum = 0;
|
||||
}
|
||||
} else
|
||||
bit_sum += pos->bit_size;
|
||||
|
||||
size = class_member__size(pos);
|
||||
/*
|
||||
* check for bitfields, accounting for only the biggest
|
||||
|
@ -692,8 +706,12 @@ void class__find_holes(struct class *self)
|
|||
last = pos;
|
||||
}
|
||||
|
||||
if (last != NULL && last->offset + last_size != self->size)
|
||||
self->padding = self->size - (last->offset + last_size);
|
||||
if (last != NULL) {
|
||||
if (last->offset + last_size != self->size)
|
||||
self->padding = self->size - (last->offset + last_size);
|
||||
if (last->bit_size != 0)
|
||||
self->bit_padding = (last_size * 8) - bit_sum;
|
||||
}
|
||||
}
|
||||
|
||||
struct class_member *class__find_member_by_name(const struct class *self,
|
||||
|
@ -913,6 +931,7 @@ static void class__print_struct(struct class *self)
|
|||
unsigned int last_cacheline = 0;
|
||||
int last_bit_size = 0;
|
||||
int last_offset = -1;
|
||||
unsigned int sum_bit_holes = 0;
|
||||
|
||||
printf("%s {\n", class__name(self, name, sizeof(name)));
|
||||
list_for_each_entry(pos, &self->members, tag.node) {
|
||||
|
@ -942,6 +961,11 @@ static void class__print_struct(struct class *self)
|
|||
"try to pack */\n\n", pos->hole);
|
||||
sum_holes += pos->hole;
|
||||
}
|
||||
if (pos->bit_hole != 0) {
|
||||
printf("\n /* XXX %d bits hole, "
|
||||
"try to pack */\n\n", pos->bit_hole);
|
||||
sum_bit_holes += pos->bit_hole;
|
||||
}
|
||||
/*
|
||||
* check for bitfields, accounting for only the biggest
|
||||
* of the byte_size in the fields in each bitfield set.
|
||||
|
@ -959,18 +983,21 @@ static void class__print_struct(struct class *self)
|
|||
last_bit_size = pos->bit_size;
|
||||
}
|
||||
|
||||
printf("}; /* size: %llu", self->size);
|
||||
printf("}; /* size: %llu, cachelines: %llu */\n", self->size,
|
||||
(self->size + cacheline_size - 1) / cacheline_size);
|
||||
if (sum_holes > 0)
|
||||
printf(", sum members: %lu, holes: %d, sum holes: %lu",
|
||||
printf(" /* sum members: %lu, holes: %d, sum holes: %lu */\n",
|
||||
sum, self->nr_holes, sum_holes);
|
||||
if (sum_bit_holes > 0)
|
||||
printf(" /* bit holes: %d, sum bit holes: %lu bits */\n",
|
||||
self->nr_bit_holes, sum_bit_holes);
|
||||
if (self->padding > 0)
|
||||
printf(", padding: %u", self->padding);
|
||||
printf(", cachelines: %llu", (self->size + cacheline_size - 1) /
|
||||
cacheline_size);
|
||||
printf(" /* padding: %u */\n", self->padding);
|
||||
if (self->bit_padding > 0)
|
||||
printf(" /* bit_padding: %u bits */\n", self->bit_padding);
|
||||
last_cacheline = self->size % cacheline_size;
|
||||
if (last_cacheline != 0)
|
||||
printf(",\n last cacheline: %u bytes", last_cacheline);
|
||||
puts(" */");
|
||||
printf(" /* last cacheline: %u bytes */\n", last_cacheline);
|
||||
|
||||
if (sum + sum_holes != self->size - self->padding)
|
||||
printf("\n/* BRAIN FART ALERT! %llu != "
|
||||
|
|
|
@ -54,7 +54,9 @@ struct class {
|
|||
uint64_t nr_entries; /* For arrays */
|
||||
unsigned short nr_members;
|
||||
unsigned short nr_holes;
|
||||
unsigned short nr_bit_holes;
|
||||
unsigned short padding;
|
||||
unsigned short bit_padding;
|
||||
unsigned int refcnt;
|
||||
signed int diff;
|
||||
struct class *class_to_diff;
|
||||
|
@ -70,6 +72,8 @@ struct class_member {
|
|||
unsigned char visited:1;
|
||||
unsigned short hole; /* If there is a hole before the next
|
||||
one (or the end of the struct) */
|
||||
unsigned short bit_hole; /* If there is a bit hole before the next
|
||||
one (or the end of the struct) */
|
||||
};
|
||||
|
||||
struct lexblock {
|
||||
|
|
Loading…
Reference in New Issue