[PATCH v12 12/17] tools/counter: Create Counter tools

David Lechner david at lechnology.com
Sun Jul 11 07:05:32 PDT 2021


On 7/11/21 6:28 AM, William Breathitt Gray wrote:
> On Sat, Jul 10, 2021 at 11:53:35AM -0500, David Lechner wrote:
>> On 7/5/21 3:19 AM, William Breathitt Gray wrote:

>>> +	{
>>> +		/* Component data: Count 0 count */
>>> +		.component.type = COUNTER_COMPONENT_COUNT,
>>> +		.component.scope = COUNTER_SCOPE_COUNT,
>>> +		.component.parent = 0,
>>> +		/* Event type: Index */
>>> +		.event = COUNTER_EVENT_INDEX,
>>> +		/* Device event channel 0 */
>>> +		.channel = 0,
>>> +	},
>>> +	{
>>> +		/* Component data: Count 1 count */
>>> +		.component.type = COUNTER_COMPONENT_COUNT,
>>> +		.component.scope = COUNTER_SCOPE_COUNT,
>>> +		.component.parent = 1,
>>> +		/* Event type: Index */
>>> +		.event = COUNTER_EVENT_INDEX,
>>> +		/* Device event channel 0 */
>>> +		.channel = 0,
>>> +	},
>>> +};
>>> +
>>> +int main(void)
>>> +{
>>> +	int fd;
>>> +	int ret;
>>> +	struct counter_event event_data[2];
>>> +
>>> +	fd = open("/dev/counter0", O_RDWR);
>>> +	if (fd == -1) {
>>> +		perror("Unable to open /dev/counter0");
>>> +		return -errno;
>>
>> errno is no longer valid after calling perror(). Since this
>> is example code, we can just return 1 instead (exit codes
>> positive number between 0 and 255 so -1 would be 255).
> 
> Ack.
> 
>>> +	}
>>> +
>>> +	ret = ioctl(fd, COUNTER_ADD_WATCH_IOCTL, watches);
>>> +	if (ret == -1) {
>>> +		perror("Error adding watches[0]");
>>> +		return -errno;
>>> +	}
>>> +	ret = ioctl(fd, COUNTER_ADD_WATCH_IOCTL, watches + 1);
>>> +	if (ret == -1) {
>>> +		perror("Error adding watches[1]");
>>> +		return -errno;
>>> +	}
>>> +	ret = ioctl(fd, COUNTER_ENABLE_EVENTS_IOCTL);
>>> +	if (ret == -1) {
>>> +		perror("Error enabling events");
>>> +		return -errno;
>>> +	}
>>> +
>>> +	for (;;) {
>>> +		ret = read(fd, event_data, sizeof(event_data));
>>> +		if (ret == -1) {
>>> +			perror("Failed to read event data");
>>> +			return -errno;
>>> +		}
>>> +
>>> +		if (ret != sizeof(event_data)) {
>>> +			fprintf(stderr, "Failed to read event data\n");
>>> +			return -EIO;
>>> +		}
>>> +
>>> +		printf("Timestamp 0: %llu\tCount 0: %llu\n"
>>> +		       "Error Message 0: %s\n"
>>> +		       "Timestamp 1: %llu\tCount 1: %llu\n"
>>> +		       "Error Message 1: %s\n",
>>> +		       (unsigned long long)event_data[0].timestamp,
>>> +		       (unsigned long long)event_data[0].value,
>>> +		       strerror(event_data[0].status),
>>> +		       (unsigned long long)event_data[1].timestamp,
>>> +		       (unsigned long long)event_data[1].value,
>>> +		       strerror(event_data[1].status));
>>> +	}
>>
>> Aren't the Count 0 and Count 1 events independent? Why should we expect to
>> always get both events at the same time in the same order?
> 
> Watch 0 and Watch 1 are both triggered by the same event: a
> COUNTER_EVENT_INDEX event on device event channel 0. If we had set
> channel to 1 for Watch 1, then we would have two independent events, but
> in this case both Watches have their respective channel set to 0.

The thing that jumped out to me is that they have different parents.
But I guess I forgot that the event itself always has a scope of
device and that the component just says what value to record and
is otherwise independent of the event.




More information about the linux-arm-kernel mailing list