Example #1
0
PerfSource::PerfSource(PerfDriver & driver, Child & child, sem_t & senderSem, sem_t & startProfile,
                       const std::set<int> & appTids, FtraceDriver & ftraceDriver, bool enableOnCommandExec, ICpuInfo & cpuInfo)
        : Source(child),
          mSummary(1024 * 1024, &senderSem),
          mCountersBuf(createPerfBufferConfig()),
          mCountersGroup(driver.getConfig(), mCountersBuf.calculateBufferLength(), gSessionData.mBacktraceDepth,
                         gSessionData.mSampleRate, gSessionData.mIsEBS, cpuInfo.getClusters(),
                         cpuInfo.getClusterIds(), getTracepointId(SCHED_SWITCH)),
          mMonitor(),
          mUEvent(),
          mAppTids(appTids),
          mDriver(driver),
          mAttrsBuffer(NULL),
          mSenderSem(senderSem),
          mStartProfile(startProfile),
          mInterruptFd(-1),
          mIsDone(false),
          mFtraceDriver(ftraceDriver),
          mCpuInfo(cpuInfo),
          mSyncThreads(),
          enableOnCommandExec(false)
{
    const PerfConfig & mConfig = mDriver.getConfig();

    if ((!mConfig.is_system_wide) && (!mConfig.has_attr_clockid_support)) {
        logg.logMessage("Tracing gatord as well as target application as no clock_id support");
        mAppTids.insert(getpid());
    }

    // was !enableOnCommandExec but this causes us to miss the exec comm record associated with the
    this->enableOnCommandExec = (enableOnCommandExec && mConfig.has_attr_clockid_support && mConfig.has_attr_comm_exec);
}
    static PerfEventType* forName(const char* name) {
        // First, look through the table of predefined perf events
        for (PerfEventType* event = AVAILABLE_EVENTS; event->name != NULL; event++) {
            if (strcmp(name, event->name) == 0) {
                return event;
            }
        }

        // Second, try kernel tracepoints defined in debugfs
        if (strchr(name, ':') != NULL) {
            int tracepoint_id = getTracepointId(name);
            if (tracepoint_id > 0) {
                KERNEL_TRACEPOINT.config = tracepoint_id;
                return  &KERNEL_TRACEPOINT;
            }
        }

        return NULL;
    }
Example #3
0
bool PerfDriver::setup() {
	// Check the kernel version
	struct utsname utsname;
	if (uname(&utsname) != 0) {
		logg->logMessage("%s(%s:%i): uname failed", __FUNCTION__, __FILE__, __LINE__);
		return false;
	}

	int release[3] = { 0, 0, 0 };
	int part = 0;
	char *ch = utsname.release;
	while (*ch >= '0' && *ch <= '9' && part < ARRAY_LENGTH(release)) {
		release[part] = 10*release[part] + *ch - '0';

		++ch;
		if (*ch == '.') {
			++part;
			++ch;
		}
	}

	if (KERNEL_VERSION(release[0], release[1], release[2]) < KERNEL_VERSION(3, 4, 0)) {
		logg->logMessage("%s(%s:%i): Unsupported kernel version", __FUNCTION__, __FILE__, __LINE__);
		return false;
	}
	mLegacySupport = KERNEL_VERSION(release[0], release[1], release[2]) < KERNEL_VERSION(3, 12, 0);

	if (access(EVENTS_PATH, R_OK) != 0) {
		logg->logMessage("%s(%s:%i): " EVENTS_PATH " does not exist, is CONFIG_TRACING enabled?", __FUNCTION__, __FILE__, __LINE__);
		return false;
	}

	// Add supported PMUs
	bool foundCpu = false;
	DIR *dir = opendir(PERF_DEVICES);
	if (dir == NULL) {
		logg->logMessage("%s(%s:%i): opendif failed", __FUNCTION__, __FILE__, __LINE__);
		return false;
	}

	struct dirent *dirent;
	while ((dirent = readdir(dir)) != NULL) {
		for (int i = 0; i < ARRAY_LENGTH(gator_cpus); ++i) {
			// Do the names match exactly?
			if (strcmp(dirent->d_name, gator_cpus[i].pmnc_name) != 0 &&
					// Do these names match but have the old vs new prefix?
			    (strncmp(dirent->d_name, OLD_PMU_PREFIX, sizeof(OLD_PMU_PREFIX) - 1) != 0 ||
			     strncmp(gator_cpus[i].pmnc_name, NEW_PMU_PREFIX, sizeof(NEW_PMU_PREFIX) - 1) != 0 ||
			     strcmp(dirent->d_name + sizeof(OLD_PMU_PREFIX) - 1, gator_cpus[i].pmnc_name + sizeof(NEW_PMU_PREFIX) - 1) != 0)) {
				continue;
			}

			int type;
			char buf[256];
			snprintf(buf, sizeof(buf), PERF_DEVICES "/%s/type", dirent->d_name);
			if (DriverSource::readIntDriver(buf, &type) != 0) {
				continue;
			}

			foundCpu = true;
			addCpuCounters(gator_cpus[i].pmnc_name, type, gator_cpus[i].pmnc_counters);
		}

		for (int i = 0; i < ARRAY_LENGTH(uncore_counters); ++i) {
			if (strcmp(dirent->d_name, uncore_counters[i].name) != 0) {
				continue;
			}

			int type;
			char buf[256];
			snprintf(buf, sizeof(buf), PERF_DEVICES "/%s/type", dirent->d_name);
			if (DriverSource::readIntDriver(buf, &type) != 0) {
				continue;
			}

			addUncoreCounters(uncore_counters[i].name, type, uncore_counters[i].count);
		}
	}
	closedir(dir);

	if (!foundCpu) {
		// If no cpu was found based on pmu names, try by cpuid
		for (int i = 0; i < ARRAY_LENGTH(gator_cpus); ++i) {
			if (gSessionData->mMaxCpuId != gator_cpus[i].cpuid) {
				continue;
			}

			foundCpu = true;
			addCpuCounters(gator_cpus[i].pmnc_name, PERF_TYPE_RAW, gator_cpus[i].pmnc_counters);
		}
	}

	/*
	if (!foundCpu) {
		// If all else fails, use the perf architected counters
		// 9 because that's how many are in events-Perf-Hardware.xml - assume they can all be enabled at once
		addCpuCounters("Perf_Hardware", PERF_TYPE_HARDWARE, 9);
	}
	*/

	// Add supported software counters
	long long id;
	DynBuf printb;

	id = getTracepointId("irq/softirq_exit", &printb);
	if (id >= 0) {
		mCounters = new PerfCounter(mCounters, "Linux_irq_softirq", PERF_TYPE_TRACEPOINT, id, true);
	}

	id = getTracepointId("irq/irq_handler_exit", &printb);
	if (id >= 0) {
		mCounters = new PerfCounter(mCounters, "Linux_irq_irq", PERF_TYPE_TRACEPOINT, id, true);
	}

	//Linux_block_rq_wr
	//Linux_block_rq_rd
	//Linux_net_rx
	//Linux_net_tx

	id = getTracepointId(SCHED_SWITCH, &printb);
	if (id >= 0) {
		mCounters = new PerfCounter(mCounters, "Linux_sched_switch", PERF_TYPE_TRACEPOINT, id, true);
	}

	//Linux_meminfo_memused
	//Linux_meminfo_memfree
	//Linux_meminfo_bufferram
	//Linux_power_cpu_freq
	//Linux_power_cpu_idle

	mCounters = new PerfCounter(mCounters, "Linux_cpu_wait_contention", TYPE_DERIVED, -1, false);

	//Linux_cpu_wait_io

	mIsSetup = true;
	return true;
}