LIBTRACEFS(3)

πŸ’… LIBTRACEFS(3) β€” the sub-buffer glow-up guide πŸŽ€

okay bestie, welcome to the libtracefs manual, and today's episode is entirely about ring buffer sub-buffers. yes we're doing this. it's giving niche but iconic. ✨


🌸 NAME 🌸

tracefs_instance_get_subbuf_size, tracefs_instance_set_subbuf_size β€” helper functions for working with ring buffer sub-buffers. literally just two little functions whose whole personality is "how big is the sub-buffer" and "make it bigger, bestie". 🫢


⭐ SYNOPSIS ⭐

#include <tracefs.h>

size_t tracefs_instance_get_subbuf_size(struct tracefs_instance *instance);
int tracefs_instance_set_subbuf_size(struct tracefs_instance *instance, size_t size);

look at them. so small. so powerful. πŸ’…


πŸ’– DESCRIPTION πŸ’–

so here's the tea β˜• β€” these are helper functions for working with the sub-buffers of the tracing ring buffer.

the tracing ring buffer? broken up into sub-buffers. that's just how it is. and an event can not be bigger than the data section of the sub-buffer (peep tep_get_sub_buffer_data_size(3) for the deets, iykyk).

by default, the ring buffer uses the architecture's page_size as the default size of the sub-buffer. and like... that can be limiting if you need big chonky events β€” for example, when the application wants to write large strings into the trace_marker file. 😭 our poor little sub-buffer can't hold it.

tracefs_instance_get_subbuf_size() returns the current size, in kilobytes, of the ring buffer sub-buffers. cute, informative, no notes. πŸ‘‘

tracefs_instance_set_subbuf_size() will write the size, in kilobytes, of what the new sub-buffer size should be. BUT β€” and this is the important part bestie, do not skip this β€”

ngl this is only a hint to what the minimum sub-buffer size should be. it also does not take into account the meta-data that is used by the sub-buffer, so the size written should be no less than 16 bytes more than the maximum event size that will be used. ⚠️

and the kernel will likely make the sub-buffer size larger than specified, because it may need to align the size for implementation purposes. so if you get bigger than you asked for, that's not a bug, that's the kernel doing its little alignment thing. slay, honestly. ✨


πŸ”₯ RETURN VALUE πŸ”₯

  • tracefs_instance_get_subbuf_size() β€” returns the size of the current sub-buffer for the given instance ring buffer, or -1 on error. πŸ’€
  • tracefs_instance_set_subbuf_size() β€” returns 0 if it successfully set the instance ring buffer sub-buffer size in kilobytes, or -1 on error. 😭

πŸ¦‹ EXAMPLE πŸ¦‹

okay this is the good part, a whole main character program. read it, don't just scroll. πŸ‘€

#include <stdlib.h>
#include <tracefs.h>
#include <errno.h>

int main(int argc, char **argv)
{
    struct tep_handle *tep;
    ssize_t save_subsize;
    ssize_t subsize;
    char *trace;
    char buf[3000];
    int meta_size;
    int ret;
    int i;

    tep = tep_alloc();
    ret = tracefs_load_headers(NULL, tep);
    tep_free(tep);

    if (ret < 0) {
        perror("reading headers");
        exit(-1);
    }

    meta_size = tep_get_sub_buffer_size(tep) - tep_get_sub_buffer_data_size(tep);

    save_subsize = tracefs_instance_get_subbuf_size(NULL);
    if (save_subsize < 0) {
        printf("Changing sub-buffer size not available\n");
        exit(-1);
    }

    subsize = save_subsize * 1024;

    /* Have at least 4 writes fit on a sub-buffer */
    if (subsize - meta_size < sizeof(buf) *4 ) {
        subsize = ((sizeof(buf) * 4 + meta_size) + 1023) / 1024;
        tracefs_instance_set_subbuf_size(NULL, subsize);
    }

    for (i = 0; i < sizeof(buf) - 1; i++) {
        buf[i] = '0' + i % 10;
    }
    buf[i] = '\0';

    tracefs_instance_clear(NULL);

    for (i = 0; i < 4; i++) {
        ret = tracefs_printf(NULL, "%s\n", buf);
        if (ret < 0)
            perror("write");
    }

    trace = tracefs_instance_file_read(NULL, "trace", NULL);
    printf("%s\n", trace);
    free(trace);

    printf("Buffer size was: %zd * 1024\n",
           tracefs_instance_get_subbuf_size(NULL));

    tracefs_instance_set_subbuf_size(NULL, save_subsize);
}

like, it saves the old size, bumps it up so at least four writes fit, does its little trace dump, then restores the original size because it's a considerate icon. we love a respectful queen. πŸŽ€


🧚 FILES 🧚

  • tracefs.h β€” header file to include in order to have access to the library APIs. yes you have to include it. no you can't skip it. πŸ™ˆ
  • -ltracefs β€” linker switch to add when building a program that uses the library. put it at the end of your compile line bestie, it's a whole vibe check for your linker. ⭐

🌈 SEE ALSO 🌈

(the whole friend group, honestly. go say hi. 🫢)


πŸ‘‘ AUTHOR πŸ‘‘

  • Steven Rostedt <rostedt@goodmis.org[1]>
  • Tzvetomir Stoyanov <tz.stoyanov@gmail.com[2]>

πŸ’€ REPORTING BUGS πŸ’€

found a bug? don't suffer in silence, tell the group chat: <linux-trace-devel@vger.kernel.org[3]> πŸ“¬


🌸 LICENSE 🌸

libtracefs is Free Software licensed under the GNU LGPL 2.1. periodt. πŸ’…


⭐ RESOURCES ⭐

https://git.kernel.org/pub/scm/libs/libtrace/libtracefs.git/

the source. the mothership. go lurk. πŸ¦‹


πŸ“ COPYING πŸ“

Copyright (C) 2020 VMware, Inc. Free use of this software is granted under the terms of the GNU Public License (GPL).


πŸŽ€ NOTES πŸŽ€

  1. rostedt@goodmis.org mailto:rostedt@goodmis.org
  2. tz.stoyanov@gmail.com mailto:tz.stoyanov@gmail.com
  3. linux-trace-devel@vger.kernel.org mailto:linux-trace-devel@vger.kernel.org

and that's the whole page bestie!! this was libtracefs 1.8.4, dated 10/21/2026 β€” go resize a sub-buffer, hydrate, and remember: 16 bytes of headroom minimum or the kernel will simply not respect you. mwah πŸ’‹πŸ’œ

πŸ“¦ where this page comes from