📄 proc_pmc.c
字号:
static inline void proc_pmc_reset(void){ /* Clear all the PMCs to zeros * Assume a "stop" has already frozen the counters * Clear all the PMCs */ mtspr( PMC1, 0 ); mtspr( PMC2, 0 ); mtspr( PMC3, 0 ); mtspr( PMC4, 0 ); mtspr( PMC5, 0 ); mtspr( PMC6, 0 ); mtspr( PMC7, 0 ); mtspr( PMC8, 0 );}static inline void proc_pmc_cpi(void){ /* Configure the PMC registers to count cycles and instructions */ /* so we can compute cpi */ /* * MMCRA[30] = 1 Don't count in wait state (CTRL[31]=0) * MMCR0[6] = 1 Freeze counters when any overflow * MMCR0[19:25] = 0x01 PMC1 counts Thread Active Run Cycles * MMCR0[26:31] = 0x05 PMC2 counts Thread Active Cycles * MMCR1[0:4] = 0x07 PMC3 counts Instructions Dispatched * MMCR1[5:9] = 0x03 PMC4 counts Instructions Completed * MMCR1[10:14] = 0x06 PMC5 counts Machine Cycles * */ proc_pmc_control_mode = PMC_CONTROL_CPI; /* Indicate to hypervisor that we are using the PMCs */ get_paca()->xLpPacaPtr->xPMCRegsInUse = 1; /* Freeze all counters */ mtspr( MMCR0, 0x80000000 ); mtspr( MMCR1, 0x00000000 ); /* Clear all the PMCs */ mtspr( PMC1, 0 ); mtspr( PMC2, 0 ); mtspr( PMC3, 0 ); mtspr( PMC4, 0 ); mtspr( PMC5, 0 ); mtspr( PMC6, 0 ); mtspr( PMC7, 0 ); mtspr( PMC8, 0 ); /* Freeze counters in Wait State (CTRL[31]=0) */ mtspr( MMCRA, 0x00000002 ); /* PMC3<-0x07, PMC4<-0x03, PMC5<-0x06 */ mtspr( MMCR1, 0x38cc0000 ); mb(); /* PMC1<-0x01, PMC2<-0x05 * Start all counters */ mtspr( MMCR0, 0x02000045 ); }static inline void proc_pmc_tlb(void){ /* Configure the PMC registers to count tlb misses */ /* * MMCR0[6] = 1 Freeze counters when any overflow * MMCR0[19:25] = 0x55 Group count * PMC1 counts I misses * PMC2 counts I miss duration (latency) * PMC3 counts D misses * PMC4 counts D miss duration (latency) * PMC5 counts IERAT misses * PMC6 counts D references (including PMC7) * PMC7 counts miss PTEs searched * PMC8 counts miss >8 PTEs searched * */ proc_pmc_control_mode = PMC_CONTROL_TLB; /* Indicate to hypervisor that we are using the PMCs */ get_paca()->xLpPacaPtr->xPMCRegsInUse = 1; /* Freeze all counters */ mtspr( MMCR0, 0x80000000 ); mtspr( MMCR1, 0x00000000 ); /* Clear all the PMCs */ mtspr( PMC1, 0 ); mtspr( PMC2, 0 ); mtspr( PMC3, 0 ); mtspr( PMC4, 0 ); mtspr( PMC5, 0 ); mtspr( PMC6, 0 ); mtspr( PMC7, 0 ); mtspr( PMC8, 0 ); mtspr( MMCRA, 0x00000000 ); mb(); /* PMC1<-0x55 * Start all counters */ mtspr( MMCR0, 0x02001540 ); }int proc_pmc_set_control( struct file *file, const char *buffer, unsigned long count, void *data ){ char stkbuf[10]; if (count > 9) count = 9; if (copy_from_user (stkbuf, buffer, count)) return -EFAULT; stkbuf[count] = 0; if ( ! strncmp( stkbuf, "stop", 4 ) ) proc_pmc_stop(); else if ( ! strncmp( stkbuf, "start", 5 ) ) proc_pmc_start(); else if ( ! strncmp( stkbuf, "reset", 5 ) ) proc_pmc_reset(); else if ( ! strncmp( stkbuf, "cpi", 3 ) ) proc_pmc_cpi(); else if ( ! strncmp( stkbuf, "tlb", 3 ) ) proc_pmc_tlb(); /* IMPLEMENT ME */ return count;}int proc_pmc_set_mmcr0( struct file *file, const char *buffer, unsigned long count, void *data ){ unsigned long v; v = proc_pmc_conv_int( buffer, count ); v = v & ~0x04000000; /* Don't allow interrupts for now */ if ( v & ~0x80000000 ) /* Inform hypervisor we are using PMCs */ get_paca()->xLpPacaPtr->xPMCRegsInUse = 1; else get_paca()->xLpPacaPtr->xPMCRegsInUse = 0; mtspr( MMCR0, v ); return count; }int proc_pmc_set_mmcr1( struct file *file, const char *buffer, unsigned long count, void *data ){ unsigned long v; v = proc_pmc_conv_int( buffer, count ); mtspr( MMCR1, v ); return count;}int proc_pmc_set_mmcra( struct file *file, const char *buffer, unsigned long count, void *data ){ unsigned long v; v = proc_pmc_conv_int( buffer, count ); v = v & ~0x00008000; /* Don't allow interrupts for now */ mtspr( MMCRA, v ); return count;}int proc_pmc_set_pmc1( struct file *file, const char *buffer, unsigned long count, void *data ){ unsigned long v; v = proc_pmc_conv_int( buffer, count ); mtspr( PMC1, v ); return count;}int proc_pmc_set_pmc2( struct file *file, const char *buffer, unsigned long count, void *data ){ unsigned long v; v = proc_pmc_conv_int( buffer, count ); mtspr( PMC2, v ); return count;}int proc_pmc_set_pmc3( struct file *file, const char *buffer, unsigned long count, void *data ){ unsigned long v; v = proc_pmc_conv_int( buffer, count ); mtspr( PMC3, v ); return count;}int proc_pmc_set_pmc4( struct file *file, const char *buffer, unsigned long count, void *data ){ unsigned long v; v = proc_pmc_conv_int( buffer, count ); mtspr( PMC4, v ); return count;}int proc_pmc_set_pmc5( struct file *file, const char *buffer, unsigned long count, void *data ){ unsigned long v; v = proc_pmc_conv_int( buffer, count ); mtspr( PMC5, v ); return count;}int proc_pmc_set_pmc6( struct file *file, const char *buffer, unsigned long count, void *data ){ unsigned long v; v = proc_pmc_conv_int( buffer, count ); mtspr( PMC6, v ); return count;}int proc_pmc_set_pmc7( struct file *file, const char *buffer, unsigned long count, void *data ){ unsigned long v; v = proc_pmc_conv_int( buffer, count ); mtspr( PMC7, v ); return count;}int proc_pmc_set_pmc8( struct file *file, const char *buffer, unsigned long count, void *data ){ unsigned long v; v = proc_pmc_conv_int( buffer, count ); mtspr( PMC8, v ); return count;}static loff_t nacamap_seek( struct file *file, loff_t off, int whence){ loff_t new; struct proc_dir_entry *dp; dp = file->f_dentry->d_inode->u.generic_ip; switch(whence) { case 0: new = off; break; case 1: new = file->f_pos + off; break; case 2: new = dp->size + off; break; default: return -EINVAL; } if ( new < 0 || new > dp->size ) return -EINVAL; return (file->f_pos = new);}static ssize_t nacamap_read( struct file *file, char *buf, size_t nbytes, loff_t *ppos){ unsigned pos = *ppos; struct proc_dir_entry *dp; dp = file->f_dentry->d_inode->u.generic_ip; if ( pos >= dp->size ) return 0; if ( nbytes >= dp->size ) nbytes = dp->size; if ( pos + nbytes > dp->size ) nbytes = dp->size - pos; copy_to_user( buf, (char *)dp->data + pos, nbytes ); *ppos = pos + nbytes; return nbytes;}static int nacamap_mmap( struct file *file, struct vm_area_struct *vma ){ struct proc_dir_entry *dp; dp = file->f_dentry->d_inode->u.generic_ip; vma->vm_flags |= VM_SHM | VM_LOCKED; if ((vma->vm_end - vma->vm_start) > dp->size) return -EINVAL; remap_page_range( vma->vm_start, __pa(dp->data), dp->size, vma->vm_page_prot ); return 0;}static int proc_ppc64_smt_snooze_read(char *page, char **start, off_t off, int count, int *eof, void *data){ if (naca->smt_snooze_delay) return sprintf(page, "%lu\n", naca->smt_snooze_delay); else return sprintf(page, "disabled\n");}static int proc_ppc64_smt_snooze_write(struct file* file, const char *buffer, unsigned long count, void *data){ unsigned long val; char val_string[22]; if (!capable(CAP_SYS_ADMIN)) return -EACCES; if (count > sizeof(val_string) - 1) return -EINVAL; if (copy_from_user(val_string, buffer, count)) return -EFAULT; val_string[count] = '\0'; if (val_string[0] == '0' && (val_string[1] == '\n' || val_string[1] == '\0')) { naca->smt_snooze_delay = 0; return count; } val = simple_strtoul(val_string, NULL, 10); if (val != 0) naca->smt_snooze_delay = val; else return -EINVAL; return count;}static int proc_ppc64_smt_state_read(char *page, char **start, off_t off, int count, int *eof, void *data){ switch(naca->smt_state) { case SMT_OFF: return sprintf(page, "off\n"); break; case SMT_ON: return sprintf(page, "on\n"); break; case SMT_DYNAMIC: return sprintf(page, "dynamic\n"); break; default: return sprintf(page, "unknown\n"); break; }}void proc_ppc64_create_smt(void){ struct proc_dir_entry *ent_snooze = create_proc_entry("smt-snooze-delay", S_IRUGO | S_IWUSR, proc_ppc64_root); struct proc_dir_entry *ent_enabled = create_proc_entry("smt-enabled", S_IRUGO | S_IWUSR, proc_ppc64_root); if (ent_snooze) { ent_snooze->nlink = 1; ent_snooze->data = NULL; ent_snooze->read_proc = (void *)proc_ppc64_smt_snooze_read; ent_snooze->write_proc = (void *)proc_ppc64_smt_snooze_write; } if (ent_enabled) { ent_enabled->nlink = 1; ent_enabled->data = NULL; ent_enabled->read_proc = (void *)proc_ppc64_smt_state_read; ent_enabled->write_proc = NULL; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -