static int gator_events_meminfo_read(long long **buffer, bool sched_switch) { #if !USE_THREAD static unsigned int last_mem_event; #endif if (!on_primary_core() || !meminfo_global_enabled) return 0; #if !USE_THREAD if (last_mem_event != mem_event) { last_mem_event = mem_event; mod_timer(&meminfo_wake_up_timer, jiffies + 1); } #endif if (!new_data_avail) return 0; new_data_avail = false; if (buffer) *buffer = meminfo_buffer; return meminfo_length; }
static int gator_events_block_read(int **buffer) { int len, value, data = 0; if (!on_primary_core()) { return 0; } len = 0; if (block_rq_wr_enabled && (value = atomic_read(&blockCnt[BLOCK_RQ_WR])) > 0) { atomic_sub(value, &blockCnt[BLOCK_RQ_WR]); blockGet[len++] = block_rq_wr_key; blockGet[len++] = 0; // indicates to Streamline that value bytes were written now, not since the last message blockGet[len++] = block_rq_wr_key; blockGet[len++] = value; data += value; } if (block_rq_rd_enabled && (value = atomic_read(&blockCnt[BLOCK_RQ_RD])) > 0) { atomic_sub(value, &blockCnt[BLOCK_RQ_RD]); blockGet[len++] = block_rq_rd_key; blockGet[len++] = 0; // indicates to Streamline that value bytes were read now, not since the last message blockGet[len++] = block_rq_rd_key; blockGet[len++] = value; data += value; } if (buffer) *buffer = blockGet; return len; }
static int gator_events_mmapped_read(int **buffer, bool sched_switch) { int i; int len = 0; int delta_in_us; struct timespec ts; s64 time; /* System wide counters - read from one core only */ if (!on_primary_core() || !mmapped_global_enabled) return 0; getnstimeofday(&ts); time = timespec_to_ns(&ts); delta_in_us = (int)(time - prev_time) / 1000; prev_time = time; for (i = 0; i < MMAPPED_COUNTERS_NUM; i++) { if (mmapped_counters[i].enabled) { mmapped_buffer[len++] = mmapped_counters[i].key; mmapped_buffer[len++] = mmapped_simulate(i, delta_in_us); } } if (buffer) *buffer = mmapped_buffer; return len; }
static int gator_events_l2c310_read(int **buffer, bool sched_switch) { static const unsigned long l2x0_event_cntx_val[L2C310_COUNTERS_NUM] = { L2X0_EVENT_CNT0_VAL, L2X0_EVENT_CNT1_VAL, }; int i; int len = 0; if (!on_primary_core()) return 0; for (i = 0; i < L2C310_COUNTERS_NUM; i++) { if (l2c310_counters[i].enabled) { l2c310_buffer[len++] = l2c310_counters[i].key; l2c310_buffer[len++] = readl(l2c310_base + l2x0_event_cntx_val[i]); } } /* l2c310 counters are saturating, not wrapping in case of overflow */ gator_events_l2c310_reset_counters(); if (buffer) *buffer = l2c310_buffer; return len; }
static int gator_events_clock_read(int **buffer, bool sched_switch) { int i; int len = 0; /* System wide counters - read from one core only */ if (!on_primary_core() || !clock_global_enabled) return 0; for (i = 0; i < CLOCK_COUNTERS_NUM; i++) { if (clock_counters[i].enabled) { clock_buffer[len++] = clock_counters[i].key; clock_buffer[len++] = get_clock_value(i); } } if (buffer) *buffer = clock_buffer; return len; }
static int read(int **buffer) { int cnt; int len = 0; long sample_interval_us = 0; struct timespec read_timestamp; if (!on_primary_core()) { return 0; } /* Get the start of this sample period. */ getnstimeofday(&read_timestamp); /* * Calculate the sample interval if the previous sample time is valid. * We use tv_sec since it will not be 0. */ if (prev_timestamp.tv_sec != 0) { sample_interval_us = get_duration_us(&prev_timestamp, &read_timestamp); } /* Structure copy. Update the previous timestamp. */ prev_timestamp = read_timestamp; /* * Report the timeline counters (ACTIVITY_START/STOP) */ for (cnt = FIRST_TIMELINE_EVENT; cnt < (FIRST_TIMELINE_EVENT + NUMBER_OF_TIMELINE_EVENTS); cnt++) { mali_counter *counter = &counters[cnt]; if (counter->enabled) { const int index = cnt - FIRST_TIMELINE_EVENT; unsigned int value; /* If the activity is still running, reset its start time to the start of this sample period * to correct the count. Add the time up to the end of the sample onto the count. */ if (timeline_event_starttime[index].tv_sec != 0) { const long event_duration = get_duration_us(&timeline_event_starttime[index], &read_timestamp); timeline_data[index] += event_duration; timeline_event_starttime[index] = read_timestamp; /* Activity is still running. */ } if (sample_interval_us != 0) { /* Convert the counter to a percent-of-sample value */ value = (timeline_data[index] * 100) / sample_interval_us; } else { pr_debug("gator: Mali-T6xx: setting value to zero\n"); value = 0; } /* Clear the counter value ready for the next sample. */ timeline_data[index] = 0; counter_dump[len++] = counter->key; counter_dump[len++] = value; } } /* Report the software counters */ for (cnt = FIRST_SOFTWARE_COUNTER; cnt < (FIRST_SOFTWARE_COUNTER + NUMBER_OF_SOFTWARE_COUNTERS); cnt++) { const mali_counter *counter = &counters[cnt]; if (counter->enabled) { const int index = cnt - FIRST_SOFTWARE_COUNTER; counter_dump[len++] = counter->key; counter_dump[len++] = sw_counter_data[index]; /* Set the value to zero for the next time */ sw_counter_data[index] = 0; } } /* Report the accumulators */ for (cnt = FIRST_ACCUMULATOR; cnt < (FIRST_ACCUMULATOR + NUMBER_OF_ACCUMULATORS); cnt++) { const mali_counter *counter = &counters[cnt]; if (counter->enabled) { const int index = cnt - FIRST_ACCUMULATOR; counter_dump[len++] = counter->key; counter_dump[len++] = accumulators_data[index]; /* Do not zero the accumulator */ } } /* Update the buffer */ if (buffer) { *buffer = (int *)counter_dump; } return len; }