Home | History | Annotate | Download | only in lib
      1 #!/usr/bin/python
      2 ''' Reusable functions related to sched mc FVT are put together
      3 '''
      4 
      5 import os
      6 import sys
      7 import re
      8 from time import time
      9 
     10 __author__ = "Vaidyanathan Srinivasan <svaidy (at] linux.vnet.ibm.com>"
     11 __author__ = "Poornima Nayak <mpnayak (at] linux.vnet.ibm.com>"
     12 
     13 
     14 cpu_map = {}
     15 stats_start = {}
     16 stats_stop = {}
     17 stats_percentage = {}
     18 intr_start = []
     19 intr_stop = []
     20 cpu_count = 0
     21 socket_count = 0
     22 cpu1_max_intr = 0
     23 cpu2_max_intr = 0
     24 intr_stat_timer_0 = []
     25 siblings_list = []
     26 
     27 def clear_dmesg():
     28     '''
     29        Clears dmesg
     30     '''
     31     try:
     32         os.system('dmesg -c >/dev/null')
     33     except OSError, e:
     34         print 'Clearing dmesg failed', e
     35         sys.exit(1)
     36 
     37 def count_num_cpu():
     38     ''' Returns number of cpu's in system
     39     '''
     40     try:
     41         cpuinfo = open('/proc/cpuinfo', 'r')
     42         global cpu_count
     43         for line in cpuinfo:
     44             if line.startswith('processor'):
     45                 cpu_count += 1
     46         cpuinfo.close()
     47     except IOError, e:
     48         print "Could not get cpu count", e
     49         sys.exit(1)
     50 
     51 def count_num_sockets():
     52     ''' Returns number of cpu's in system
     53     '''
     54     socket_list = []
     55     global socket_count
     56     try:
     57         for i in range(0, cpu_count):
     58             phy_pkg_file = '/sys/devices/system/cpu/cpu%s' % i
     59             phy_pkg_file += '/topology/physical_package_id'
     60             socket_id = open(phy_pkg_file).read().rstrip()
     61             if socket_id not in socket_list:
     62                 socket_list.append(socket_id)
     63                 socket_count = socket_count + 1
     64     except Exception, details:
     65         print "INFO: Failed to get number of sockets in system", details
     66         sys.exit(1)
     67 
     68 def is_multi_socket():
     69     '''Return 1 if the system is multi socket else return 0
     70     '''
     71     try:
     72         if socket_count > 1:
     73             return 1
     74         else:
     75             return 0
     76     except Exception:
     77         print "Failed to check if system is multi socket system"
     78         sys.exit(1)
     79 
     80 def is_hyper_threaded():
     81     '''Return 1 if the system is hyper threaded else return 0
     82     '''
     83     try:
     84         file_cpuinfo = open("/proc/cpuinfo", 'r')
     85         for line in file_cpuinfo:
     86             if line.startswith('siblings'):
     87                 siblings = line.split(":")
     88             if line.startswith('cpu cores'):
     89                 cpu_cores = line.split(":")
     90                 break
     91         if int( siblings[1] ) / int( cpu_cores[1] )> 1:
     92             file_cpuinfo.close()
     93             return 1
     94         else:
     95             return 0
     96     except Exception:
     97         print "Failed to check if system is hyper-threaded"
     98         sys.exit(1)
     99 
    100 def is_multi_core():
    101     ''' Return true if system has sockets has multiple cores
    102     '''
    103 
    104     try:
    105         file_cpuinfo = open("/proc/cpuinfo", 'r')
    106         for line in file_cpuinfo:
    107             if line.startswith('siblings'):
    108                 siblings = line.split(":")
    109             if line.startswith('cpu cores'):
    110                 cpu_cores = line.split(":")
    111                 break
    112 
    113         if int( siblings[1] ) == int( cpu_cores[1] ):
    114             if int( cpu_cores[1] ) > 1:
    115                 multi_core = 1
    116             else:
    117                 multi_core = 0
    118         else:
    119             num_of_cpus = int(siblings[1]) / int(cpu_cores[1])
    120             if num_of_cpus > 1:
    121                 multi_core = 1
    122             else:
    123                 multi_core = 0
    124         file_cpuinfo.close()
    125         return multi_core
    126     except Exception:
    127         print "Failed to check if system is multi core system"
    128         sys.exit(1)
    129 
    130 def get_hyper_thread_count():
    131     ''' Return number of threads in CPU. For eg for x3950 this function
    132         would return 2. In future if 4 threads are supported in CPU, this
    133         routine would return 4
    134     '''
    135     try:
    136         file_cpuinfo = open("/proc/cpuinfo", 'r')
    137         for line in file_cpuinfo:
    138             if line.startswith('siblings'):
    139                 siblings = line.split(":")
    140             if line.startswith('cpu cores'):
    141                 cpu_cores = line.split(":")
    142                 break
    143         return( int( siblings[1] ) / int( cpu_cores[1] ) )
    144     except Exception:
    145         print "Failed to check if system is hyper-threaded"
    146         sys.exit(1)
    147 
    148 def map_cpuid_pkgid():
    149     ''' Routine to map physical package id to cpu id
    150     '''
    151     if is_hyper_threaded():
    152         core_info = {}
    153         try:
    154             for i in range(0, cpu_count):
    155                 phy_pkg_file = '/sys/devices/system/cpu/cpu%s' % i
    156                 phy_pkg_file += '/topology/physical_package_id'
    157                 core_file = '/sys/devices/system/cpu/cpu%s' % i
    158                 core_file += '/topology/core_id'
    159                 core_id = open(core_file).read().rstrip()
    160                 cpu_phy_id = open(phy_pkg_file).read().rstrip()
    161                 if not cpu_phy_id in cpu_map.keys():
    162                     core_info = {}
    163                 else:
    164                     core_info = cpu_map[cpu_phy_id]
    165                 if not core_id in core_info.keys():
    166                     core_info[core_id] = [i]
    167                 else:
    168                     core_info[core_id].append(i)
    169                 cpu_map[cpu_phy_id] = core_info
    170         except Exception, details:
    171             print "Package, core & cpu map table creation failed", e
    172             sys.exit(1)
    173     else:
    174         for i in range(0, cpu_count):
    175             try:
    176                 phy_pkg_file = '/sys/devices/system/cpu/cpu%s' %i
    177                 phy_pkg_file += '/topology/physical_package_id'
    178                 cpu_phy_id = open(phy_pkg_file).read().rstrip()
    179                 if not cpu_phy_id in cpu_map.keys():
    180                     cpu_map[cpu_phy_id] = [i]
    181                 else:
    182                     cpu_map[cpu_phy_id].append(i)
    183             except IOError, e:
    184                 print "Mapping of CPU to pkg id failed", e
    185                 sys.exit(1)
    186 
    187 
    188 def generate_sibling_list():
    189     ''' Routine to generate siblings list
    190     '''
    191     try:
    192         for i in range(0, cpu_count):
    193             siblings_file = '/sys/devices/system/cpu/cpu%s' % i
    194             siblings_file += '/topology/thread_siblings_list'
    195             threads_sibs = open(siblings_file).read().rstrip()
    196             thread_ids = threads_sibs.split("-")
    197 
    198             if not thread_ids in siblings_list:
    199                 siblings_list.append(thread_ids)
    200     except Exception, details:
    201         print "Exception in generate_siblings_list", details
    202         sys.exit(1)
    203 
    204 def get_siblings(cpu_id):
    205     ''' Return siblings of cpu_id
    206     '''
    207     try:
    208         cpus = ""
    209         for i in range(0, len(siblings_list)):
    210             for cpu in siblings_list[i]:
    211                 if cpu_id == cpu:
    212                     for j in siblings_list[i]:
    213                         # Exclude cpu_id in the list of siblings
    214                         if j != cpu_id:
    215                             cpus += j
    216                     return cpus
    217         return cpus
    218     except Exception, details:
    219         print "Exception in get_siblings", details
    220         sys.exit(1)
    221 
    222 def get_proc_data(stats_list):
    223     ''' Read /proc/stat info and store in dictionary
    224     '''
    225     try:
    226         file_procstat = open("/proc/stat", 'r')
    227         for line in file_procstat:
    228             if line.startswith('cpu'):
    229                 data = line.split()
    230                 stats_list[data[0]] = data
    231         file_procstat.close()
    232     except OSError, e:
    233         print "Could not read statistics", e
    234         sys.exit(1)
    235 
    236 def get_proc_loc_count(loc_stats):
    237     ''' Read /proc/interrupts info and store in list
    238     '''
    239     try:
    240         file_procstat = open("/proc/interrupts", 'r')
    241         for line in file_procstat:
    242             if line.startswith(' LOC:') or line.startswith('LOC:'):
    243                 data = line.split()
    244                 for i in range(0, cpu_count):
    245                     # To skip LOC
    246                     loc_stats.append(data[i+1])
    247                 file_procstat.close()
    248                 return
    249     except Exception, details:
    250         print "Could not read interrupt statistics", details
    251         sys.exit(1)
    252 
    253 
    254 def set_sched_mc_power(sched_mc_level):
    255     ''' Routine to set sched_mc_power_savings to required level
    256     '''
    257     try:
    258         os.system('echo %s > \
    259             /sys/devices/system/cpu/sched_mc_power_savings 2>/dev/null'
    260             % sched_mc_level)
    261 
    262         get_proc_data(stats_start)
    263     except OSError, e:
    264         print "Could not set sched_mc_power_savings to", sched_mc_level, e
    265 	sys.exit(1)
    266 
    267 def set_sched_smt_power(sched_smt_level):
    268     ''' Routine to set sched_smt_power_savings to required level
    269     '''
    270     try:
    271         os.system('echo %s > \
    272             /sys/devices/system/cpu/sched_smt_power_savings 2>/dev/null'
    273             % sched_smt_level)
    274 
    275         get_proc_data(stats_start)
    276     except OSError, e:
    277         print "Could not set sched_smt_power_savings to", sched_smt_level, e
    278 	sys.exit(1)
    279 
    280 def set_timer_migration_interface(value):
    281     ''' Set value of timer migration interface to a value
    282         passed as argument
    283     '''
    284     try:
    285         os.system('echo %s > \
    286             /proc/sys/kernel/timer_migration 2>/dev/null' % value)
    287     except OSError, e:
    288         print "Could not set timer_migration to ", value, e
    289         sys.exit(1)
    290 
    291 def get_job_count(stress, workload, sched_smt):
    292     ''' Returns number of jobs/threads to be triggered
    293     '''
    294 
    295     try:
    296         if stress == "thread":
    297             threads = get_hyper_thread_count()
    298         if stress == "partial":
    299             threads = cpu_count / socket_count
    300             if is_hyper_threaded():
    301                 if workload == "ebizzy" and int(sched_smt) ==0:
    302                     threads = threads / get_hyper_thread_count()
    303                 if workload == "kernbench" and int(sched_smt) < 2:
    304                     threads = threads / get_hyper_thread_count()
    305         if stress == "full":
    306             threads = cpu_count
    307         if stress == "single_job":
    308             threads = 1
    309             duration = 180
    310         return threads
    311     except Exception, details:
    312         print "get job count failed ", details
    313         sys.exit(1)
    314 
    315 def trigger_ebizzy (sched_smt, stress, duration, background, pinned):
    316     ''' Triggers ebizzy workload for sched_mc=1
    317         testing
    318     '''
    319     try:
    320         threads = get_job_count(stress, "ebizzy", sched_smt)
    321         workload = "ebizzy"
    322         olddir = os.getcwd()
    323         path = '%s/testcases/bin' % os.environ['LTPROOT']
    324         os.chdir(path)
    325         workload_file = ""
    326         for file_name in os.listdir('.'):
    327             if file_name == workload:
    328                 workload_file = file_name
    329                 break
    330         if workload_file == "":
    331             print "INFO: ebizzy benchmark not found"
    332             os.chdir(olddir)
    333             sys.exit(1)
    334         get_proc_data(stats_start)
    335         get_proc_loc_count(intr_start)
    336         try:
    337             if background == "yes":
    338                 succ = os.system('./ebizzy -t%s -s4096 -S %s >/dev/null &'
    339                     % (threads, duration))
    340             else:
    341                 if pinned == "yes":
    342                     succ = os.system('taskset -c %s ./ebizzy -t%s -s4096 -S %s >/dev/null'
    343                         % (cpu_count -1, threads, duration))
    344                 else:
    345                     succ = os.system('./ebizzy -t%s -s4096 -S %s >/dev/null'
    346                         % (threads, duration))
    347 
    348             if succ == 0:
    349                 print "INFO: ebizzy workload triggerd"
    350                 os.chdir(olddir)
    351                 #Commented bcoz it doesnt make sense to capture it when workload triggered
    352                 #in background
    353                 #get_proc_loc_count(intr_stop)
    354                 #get_proc_data(stats_stop)
    355             else:
    356                 print "INFO: ebizzy workload triggerd failed"
    357                 os.chdir(olddir)
    358                 sys.exit(1)
    359         except Exception, details:
    360             print "Ebizzy workload trigger failed ", details
    361             sys.exit(1)
    362     except Exception, details:
    363         print "Ebizzy workload trigger failed ", details
    364         sys.exit(1)
    365 
    366 def trigger_kernbench (sched_smt, stress, background, pinned, perf_test):
    367     ''' Trigger load on system like kernbench.
    368         Copys existing copy of LTP into as LTP2 and then builds it
    369         with make -j
    370     '''
    371     olddir = os.getcwd()
    372     try:
    373         threads = get_job_count(stress, "kernbench", sched_smt)
    374 
    375         dst_path = "/root"
    376         workload = "kernbench"
    377         olddir = os.getcwd()
    378         path = '%s/testcases/bin' % os.environ['LTPROOT']
    379         os.chdir(path)
    380         workload_file = ""
    381         for file_name in os.listdir('.'):
    382             if file_name == workload:
    383                 workload_file = file_name
    384                 break
    385         if workload_file != "":
    386             benchmark_path = path
    387         else:
    388             print "INFO: kernbench benchmark not found"
    389             os.chdir(olddir)
    390             sys.exit(1)
    391 
    392         os.chdir(dst_path)
    393         linux_source_dir=""
    394         for file_name in os.listdir('.'):
    395             if file_name.find("linux-2.6") != -1 and os.path.isdir(file_name):
    396                 linux_source_dir=file_name
    397                 break
    398         if linux_source_dir != "":
    399             os.chdir(linux_source_dir)
    400         else:
    401             print "INFO: Linux kernel source not found in /root. Workload\
    402                Kernbench cannot be executed"
    403             sys.exit(1)
    404 
    405         get_proc_data(stats_start)
    406         get_proc_loc_count(intr_start)
    407         if pinned == "yes":
    408             os.system ( 'taskset -c %s %s/kernbench -o %s -M -H -n 1 \
    409                 >/dev/null 2>&1 &' % (cpu_count-1, benchmark_path, threads))
    410 
    411             # We have to delete import in future
    412             import time
    413             time.sleep(240)
    414             stop_wkld("kernbench")
    415         else:
    416             if background == "yes":
    417                 os.system ( '%s/kernbench -o %s -M -H -n 1 >/dev/null 2>&1 &' \
    418                     % (benchmark_path, threads))
    419             else:
    420                 if perf_test == "yes":
    421                     os.system ( '%s/kernbench -o %s -M -H -n 1 >/dev/null 2>&1' \
    422                         % (benchmark_path, threads))
    423                 else:
    424                     os.system ( '%s/kernbench -o %s -M -H -n 1 >/dev/null 2>&1 &' \
    425                         % (benchmark_path, threads))
    426                     # We have to delete import in future
    427                     import time
    428                     time.sleep(240)
    429                     stop_wkld("kernbench")
    430 
    431         print "INFO: Workload kernbench triggerd"
    432         os.chdir(olddir)
    433     except Exception, details:
    434         print "Workload kernbench trigger failed ", details
    435         sys.exit(1)
    436 
    437 def trigger_workld(sched_smt, workload, stress, duration, background, pinned, perf_test):
    438     ''' Triggers workload passed as argument. Number of threads
    439         triggered is based on stress value.
    440     '''
    441     try:
    442         if workload == "ebizzy":
    443             trigger_ebizzy (sched_smt, stress, duration, background, pinned)
    444         if workload == "kernbench":
    445             trigger_kernbench (sched_smt, stress, background, pinned, perf_test)
    446     except Exception, details:
    447         print "INFO: Trigger workload failed", details
    448         sys.exit(1)
    449 
    450 def generate_report():
    451     ''' Generate report of CPU utilization
    452     '''
    453     cpu_labels = ('cpu', 'user', 'nice', 'system', 'idle', 'iowait', 'irq',
    454 	'softirq', 'x', 'y')
    455     if (not os.path.exists('/procstat')):
    456         os.mkdir('/procstat')
    457 
    458     get_proc_data(stats_stop)
    459 
    460     reportfile = open('/procstat/cpu-utilisation', 'a')
    461     debugfile = open('/procstat/cpu-utilisation.debug', 'a')
    462     for l in stats_stop:
    463         percentage_list = []
    464         total = 0
    465         for i in range(1, len(stats_stop[l])):
    466             stats_stop[l][i] =  int(stats_stop[l][i]) - int(stats_start[l][i])
    467             total += stats_stop[l][i]
    468         percentage_list.append(l)
    469         for i in range(1, len(stats_stop[l])):
    470             percentage_list.append(float(stats_stop[l][i])*100/total)
    471 
    472         stats_percentage[l] = percentage_list
    473 
    474     for i in range(0, len(cpu_labels)):
    475         print >> debugfile, cpu_labels[i], '\t',
    476     print >> debugfile
    477     for l in sorted(stats_stop.keys()):
    478         print >> debugfile, l, '\t',
    479         for i in range(1, len(stats_stop[l])):
    480             print >> debugfile, stats_stop[l][i], '\t',
    481         print >> debugfile
    482 
    483     for i in range(0, len(cpu_labels)):
    484         print >> reportfile, cpu_labels[i], '\t',
    485     print >> reportfile
    486     for l in sorted(stats_percentage.keys()):
    487         print >> reportfile, l, '\t',
    488         for i in range(1, len(stats_percentage[l])):
    489             print >> reportfile, " %3.4f" % stats_percentage[l][i],
    490         print >> reportfile
    491 
    492     #Now get the package ID information
    493     try:
    494         print >> debugfile, "cpu_map: ", cpu_map
    495         keyvalfile = open('/procstat/keyval', 'a')
    496         print >> keyvalfile, "nr_packages=%d" % len(cpu_map)
    497         print >> keyvalfile, "system-idle=%3.4f" % (stats_percentage['cpu'][4])
    498         for pkg in sorted(cpu_map.keys()):
    499             if is_hyper_threaded():
    500                 for core in sorted(cpu_map[pkg].keys()):
    501                     total_idle = 0
    502                     total = 0
    503                     for cpu in cpu_map[pkg][core]:
    504                         total_idle += stats_stop["cpu%d" % cpu][4]
    505                         for i in range(1, len(stats_stop["cpu%d" % cpu])):
    506                             total += stats_stop["cpu%d" % cpu][i]
    507             else:
    508                 total_idle = 0
    509                 total = 0
    510                 for cpu in cpu_map[pkg]:
    511                     total_idle += stats_stop["cpu%d" % cpu][4]
    512                     for i in range(1, len(stats_stop["cpu%d" % cpu])):
    513                         total += stats_stop["cpu%d" % cpu][i]
    514             print >> reportfile, "Package: ", pkg, "Idle %3.4f%%" \
    515 	        % (float(total_idle)*100/total)
    516             print >> keyvalfile, "package-%s=%3.4f" % \
    517 		(pkg, (float(total_idle)*100/total))
    518     except Exception, details:
    519         print "Generating utilization report failed: ", details
    520         sys.exit(1)
    521 
    522     #Add record delimiter '\n' before closing these files
    523     print >> debugfile
    524     debugfile.close()
    525     print >> reportfile
    526     reportfile.close()
    527     print >> keyvalfile
    528     keyvalfile.close()
    529 
    530 def generate_loc_intr_report():
    531     ''' Generate interrupt report of CPU's
    532     '''
    533     try:
    534         if (not os.path.exists('/procstat')):
    535             os.mkdir('/procstat')
    536 
    537         get_proc_loc_count(intr_stop)
    538 
    539         reportfile = open('/procstat/cpu-loc_interrupts', 'a')
    540         print >> reportfile, "=============================================="
    541         print >> reportfile, "     Local timer interrupt stats              "
    542         print >> reportfile, "=============================================="
    543 
    544         for i in range(0, cpu_count):
    545             intr_stop[i] =  int(intr_stop[i]) - int(intr_start[i])
    546             print >> reportfile, "CPU%s: %s" %(i, intr_stop[i])
    547         print >> reportfile
    548         reportfile.close()
    549     except Exception, details:
    550         print "Generating interrupt report failed: ", details
    551         sys.exit(1)
    552 
    553 def record_loc_intr_count():
    554     ''' Record Interrupt statistics when timer_migration
    555         was disabled
    556     '''
    557     try:
    558         global intr_start, intr_stop
    559         for i in range(0, cpu_count):
    560             intr_stat_timer_0.append(intr_stop[i])
    561         intr_start = []
    562         intr_stop = []
    563     except Exception, details:
    564         print "INFO: Record interrupt statistics when timer_migration=0",details
    565 
    566 def expand_range(range_val):
    567     '''
    568        Expand the range of value into actual numbers
    569     '''
    570     ids_list = list()
    571     try:
    572         sep_comma = range_val.split(",")
    573         for i in range(0, len(sep_comma)):
    574             hyphen_values = sep_comma[i].split("-")
    575             if len(hyphen_values) == 1:
    576                 ids_list.append(int(hyphen_values[0]))
    577             else:
    578                 for j in range(int(hyphen_values[0]), int(hyphen_values[1])+1):
    579                     ids_list.append(j)
    580         return(ids_list)
    581     except Exception, details:
    582         print "INFO: expand_pkg_grps failed ", details
    583 
    584 def is_quad_core():
    585     '''
    586        Read /proc/cpuinfo and check if system is Quad core
    587     '''
    588     try:
    589         cpuinfo = open('/proc/cpuinfo', 'r')
    590         for line in cpuinfo:
    591             if line.startswith('cpu cores'):
    592                 cores = line.split("cpu cores")
    593                 num_cores = cores[1].split(":")
    594                 cpuinfo.close()
    595                 if int(num_cores[1]) == 4:
    596                     return(1)
    597                 else:
    598                     return(0)
    599     except IOError, e:
    600         print "Failed to get cpu core information", e
    601         sys.exit(1)
    602 
    603 def validate_cpugrp_map(cpu_group, sched_mc_level, sched_smt_level):
    604     '''
    605        Verify if cpugrp belong to same package
    606     '''
    607     modi_cpu_grp = cpu_group[:]
    608     try:
    609         if is_hyper_threaded():
    610             for pkg in sorted(cpu_map.keys()):
    611                 # if CPU utilized is across package this condition will be true
    612                 if len(modi_cpu_grp) != len(cpu_group):
    613                     break
    614                 for core in sorted(cpu_map[pkg].keys()):
    615                     core_cpus = cpu_map[pkg][core]
    616                     if core_cpus == modi_cpu_grp:
    617                         return 0
    618                     else:
    619                         #if CPUs used across the cores
    620                         for i in range(0, len(core_cpus)):
    621                             if core_cpus[i] in modi_cpu_grp:
    622                                 modi_cpu_grp.remove(core_cpus[i])
    623                                 if len(modi_cpu_grp) == 0:
    624                                     return 0
    625                             #This code has to be deleted
    626                             #else:
    627                                 # If sched_smt == 0 then its oky if threads run
    628                                 # in different cores of same package
    629                                 #if sched_smt_level > 0 :
    630                                     #return 1
    631 	else:
    632             for pkg in sorted(cpu_map.keys()):
    633                 pkg_cpus = cpu_map[pkg]
    634                 if len(cpu_group) == len(pkg_cpus):
    635                     if pkg_cpus == cpu_group:
    636                         return(0)
    637                 else:
    638                     if int(cpus_utilized[0]) in cpu_map[pkg] or int(cpus_utilized[1]) in cpu_map[pkg]:
    639                         return(0)
    640 
    641         return(1)
    642 
    643     except Exception, details:
    644         print "Exception in validate_cpugrp_map: ", details
    645         sys.exit(1)
    646 
    647 
    648 def verify_sched_domain_dmesg(sched_mc_level, sched_smt_level):
    649     '''
    650        Read sched domain information from dmesg.
    651     '''
    652     cpu_group = list()
    653     try:
    654         dmesg_info = os.popen('dmesg').read()
    655         if dmesg_info != "":
    656             lines = dmesg_info.split('\n')
    657             for i in range(0, len(lines)):
    658                 if lines[i].endswith('CPU'):
    659                     groups = lines[i+1].split("groups:")
    660                     group_info = groups[1]
    661                     if group_info.find("(") != -1:
    662                         openindex=group_info.index("(")
    663                         closeindex=group_info.index(")")
    664                         group_info=group_info.replace\
    665                             (group_info[openindex:closeindex+1],"")
    666 
    667                     subgroup = group_info.split(",")
    668                     for j in range(0, len(subgroup)):
    669                         cpu_group = expand_range(subgroup[j])
    670                         status = validate_cpugrp_map(cpu_group, sched_mc_level,\
    671                         sched_smt_level)
    672                         if status == 1:
    673                             if is_quad_core() == 1:
    674                                 if int(sched_mc_level) == 0:
    675                                     return(0)
    676                                 else:
    677                                     return(1)
    678                             else:
    679                                 return(1)
    680             return(0)
    681         else:
    682             return(1)
    683     except Exception, details:
    684         print "Reading dmesg failed", details
    685         sys.exit(1)
    686 
    687 def get_cpu_utilization(cpu):
    688     ''' Return cpu utilization of cpu_id
    689     '''
    690     try:
    691         for l in sorted(stats_percentage.keys()):
    692             if cpu == stats_percentage[l][0]:
    693                 return stats_percentage[l][1]
    694         return -1
    695     except Exception, details:
    696         print "Exception in get_cpu_utilization", details
    697         sys.exit(1)
    698 
    699 def validate_cpu_consolidation(stress, work_ld, sched_mc_level, sched_smt_level):
    700     ''' Verify if cpu's on which threads executed belong to same
    701     package
    702     '''
    703     cpus_utilized = list()
    704     threads = get_job_count(stress, work_ld, sched_smt_level)
    705     try:
    706         for l in sorted(stats_percentage.keys()):
    707             #modify threshold
    708             cpu_id = stats_percentage[l][0].split("cpu")
    709             if cpu_id[1] == '':
    710                 continue
    711             if int(cpu_id[1]) in cpus_utilized:
    712                 continue
    713             if is_hyper_threaded():
    714                 if work_ld == "kernbench" and sched_smt_level < sched_mc_level:
    715                     siblings = get_siblings(cpu_id[1])
    716                     if siblings != "":
    717                         sib_list = siblings.split()
    718                         utilization = int(stats_percentage[l][1])
    719                         for i in range(0, len(sib_list)):
    720                             utilization += int(get_cpu_utilization("cpu%s" %sib_list[i]))
    721                     else:
    722                         utilization = stats_percentage[l][1]
    723                     if utilization > 40:
    724                         cpus_utilized.append(int(cpu_id[1]))
    725                         if siblings != "":
    726                             for i in range(0, len(sib_list)):
    727                                 cpus_utilized.append(int(sib_list[i]))
    728                 else:
    729                     # This threshold wuld be modified based on results
    730                     if stats_percentage[l][1] > 40:
    731                         cpus_utilized.append(int(cpu_id[1]))
    732             else:
    733                 if work_ld == "kernbench" :
    734                     if stats_percentage[l][1] > 50:
    735                         cpus_utilized.append(int(cpu_id[1]))
    736                 else:
    737                     if stats_percentage[l][1] > 70:
    738                         cpus_utilized.append(int(cpu_id[1]))
    739             cpus_utilized.sort()
    740         print "INFO: CPU's utilized ", cpus_utilized
    741 
    742         # If length of CPU's utilized is not = number of jobs exit with 1
    743         if len(cpus_utilized) < threads:
    744             return 1
    745 
    746         status = validate_cpugrp_map(cpus_utilized, sched_mc_level, \
    747             sched_smt_level)
    748         if status == 1:
    749             print "INFO: CPUs utilized is not in same package or core"
    750 
    751         return(status)
    752     except Exception, details:
    753         print "Exception in validate_cpu_consolidation: ", details
    754         sys.exit(1)
    755 
    756 def get_cpuid_max_intr_count():
    757     '''Return the cpu id's of two cpu's with highest number of intr'''
    758     try:
    759         highest = 0
    760         second_highest = 0
    761         cpus_utilized = []
    762 
    763         #Skipping CPU0 as it is generally high
    764         for i in range(1, cpu_count):
    765             if int(intr_stop[i]) > int(highest):
    766                 if highest != 0:
    767                     second_highest = highest
    768                     cpu2_max_intr = cpu1_max_intr
    769                 highest = int(intr_stop[i])
    770                 cpu1_max_intr = i
    771             else:
    772                 if int(intr_stop[i]) > int(second_highest):
    773                     second_highest = int(intr_stop[i])
    774                     cpu2_max_intr = i
    775         cpus_utilized.append(cpu1_max_intr)
    776         cpus_utilized.append(cpu2_max_intr)
    777 
    778         for i in range(1, cpu_count):
    779             if i != cpu1_max_intr and i != cpu2_max_intr:
    780                 diff = second_highest - intr_stop[i]
    781                 ''' Threshold of difference has to be manipulated '''
    782                 if diff < 10000:
    783                     print "INFO: Diff in interrupt count is below threshold"
    784                     cpus_utilized = []
    785                     return cpus_utilized
    786         print "INFO: Interrupt count in other CPU's low as expected"
    787         return cpus_utilized
    788     except Exception, details:
    789         print "Exception in get_cpuid_max_intr_count: ", details
    790         sys.exit(1)
    791 
    792 def validate_ilb (sched_mc_level, sched_smt_level):
    793     ''' Validate if ilb is running in same package where work load is running
    794     '''
    795     try:
    796         cpus_utilized = get_cpuid_max_intr_count()
    797         if not cpus_utilized:
    798             return 1
    799 
    800         status = validate_cpugrp_map(cpus_utilized, sched_mc_level, sched_smt_level)
    801         return status
    802     except Exception, details:
    803         print "Exception in validate_ilb: ", details
    804         sys.exit(1)
    805 
    806 def reset_schedmc():
    807     ''' Routine to reset sched_mc_power_savings to Zero level
    808     '''
    809     try:
    810         os.system('echo 0 > \
    811             /sys/devices/system/cpu/sched_mc_power_savings 2>/dev/null')
    812     except OSError, e:
    813         print "Could not set sched_mc_power_savings to 0", e
    814         sys.exit(1)
    815 
    816 def reset_schedsmt():
    817     ''' Routine to reset sched_smt_power_savings to Zero level
    818     '''
    819     try:
    820         os.system('echo 0 > \
    821             /sys/devices/system/cpu/sched_smt_power_savings 2>/dev/null')
    822     except OSError, e:
    823         print "Could not set sched_smt_power_savings to 0", e
    824         sys.exit(1)
    825 
    826 def stop_wkld(work_ld):
    827     ''' Kill workload triggered in background
    828     '''
    829     try:
    830         os.system('pkill %s 2>/dev/null' %work_ld)
    831         if work_ld == "kernbench":
    832             os.system('pkill make 2>/dev/null')
    833     except OSError, e:
    834         print "Exception in stop_wkld", e
    835         sys.exit(1)
    836