17a8e76a3SSteven Rostedt /* 27a8e76a3SSteven Rostedt * Generic ring buffer 37a8e76a3SSteven Rostedt * 47a8e76a3SSteven Rostedt * Copyright (C) 2008 Steven Rostedt <[email protected]> 57a8e76a3SSteven Rostedt */ 6af658dcaSSteven Rostedt (Red Hat) #include <linux/trace_events.h> 77a8e76a3SSteven Rostedt #include <linux/ring_buffer.h> 814131f2fSIngo Molnar #include <linux/trace_clock.h> 9e6017571SIngo Molnar #include <linux/sched/clock.h> 100b07436dSSteven Rostedt #include <linux/trace_seq.h> 117a8e76a3SSteven Rostedt #include <linux/spinlock.h> 1215693458SSteven Rostedt (Red Hat) #include <linux/irq_work.h> 137a8e76a3SSteven Rostedt #include <linux/uaccess.h> 14a81bd80aSSteven Rostedt #include <linux/hardirq.h> 156c43e554SSteven Rostedt (Red Hat) #include <linux/kthread.h> /* for self test */ 167a8e76a3SSteven Rostedt #include <linux/module.h> 177a8e76a3SSteven Rostedt #include <linux/percpu.h> 187a8e76a3SSteven Rostedt #include <linux/mutex.h> 196c43e554SSteven Rostedt (Red Hat) #include <linux/delay.h> 205a0e3ad6STejun Heo #include <linux/slab.h> 217a8e76a3SSteven Rostedt #include <linux/init.h> 227a8e76a3SSteven Rostedt #include <linux/hash.h> 237a8e76a3SSteven Rostedt #include <linux/list.h> 24554f786eSSteven Rostedt #include <linux/cpu.h> 257a8e76a3SSteven Rostedt 2679615760SChristoph Lameter #include <asm/local.h> 27182e9f5fSSteven Rostedt 2883f40318SVaibhav Nagarnaik static void update_pages_handler(struct work_struct *work); 2983f40318SVaibhav Nagarnaik 30033601a3SSteven Rostedt /* 31d1b182a8SSteven Rostedt * The ring buffer header is special. We must manually up keep it. 32d1b182a8SSteven Rostedt */ 33d1b182a8SSteven Rostedt int ring_buffer_print_entry_header(struct trace_seq *s) 34d1b182a8SSteven Rostedt { 35c0cd93aaSSteven Rostedt (Red Hat) trace_seq_puts(s, "# compressed entry header\n"); 36c0cd93aaSSteven Rostedt (Red Hat) trace_seq_puts(s, "\ttype_len : 5 bits\n"); 37c0cd93aaSSteven Rostedt (Red Hat) trace_seq_puts(s, "\ttime_delta : 27 bits\n"); 38c0cd93aaSSteven Rostedt (Red Hat) trace_seq_puts(s, "\tarray : 32 bits\n"); 39c0cd93aaSSteven Rostedt (Red Hat) trace_seq_putc(s, '\n'); 40c0cd93aaSSteven Rostedt (Red Hat) trace_seq_printf(s, "\tpadding : type == %d\n", 41d1b182a8SSteven Rostedt RINGBUF_TYPE_PADDING); 42c0cd93aaSSteven Rostedt (Red Hat) trace_seq_printf(s, "\ttime_extend : type == %d\n", 43d1b182a8SSteven Rostedt RINGBUF_TYPE_TIME_EXTEND); 44c0cd93aaSSteven Rostedt (Red Hat) trace_seq_printf(s, "\tdata max type_len == %d\n", 45334d4169SLai Jiangshan RINGBUF_TYPE_DATA_TYPE_LEN_MAX); 46d1b182a8SSteven Rostedt 47c0cd93aaSSteven Rostedt (Red Hat) return !trace_seq_has_overflowed(s); 48d1b182a8SSteven Rostedt } 49d1b182a8SSteven Rostedt 50d1b182a8SSteven Rostedt /* 515cc98548SSteven Rostedt * The ring buffer is made up of a list of pages. A separate list of pages is 525cc98548SSteven Rostedt * allocated for each CPU. A writer may only write to a buffer that is 535cc98548SSteven Rostedt * associated with the CPU it is currently executing on. A reader may read 545cc98548SSteven Rostedt * from any per cpu buffer. 555cc98548SSteven Rostedt * 565cc98548SSteven Rostedt * The reader is special. For each per cpu buffer, the reader has its own 575cc98548SSteven Rostedt * reader page. When a reader has read the entire reader page, this reader 585cc98548SSteven Rostedt * page is swapped with another page in the ring buffer. 595cc98548SSteven Rostedt * 605cc98548SSteven Rostedt * Now, as long as the writer is off the reader page, the reader can do what 615cc98548SSteven Rostedt * ever it wants with that page. The writer will never write to that page 625cc98548SSteven Rostedt * again (as long as it is out of the ring buffer). 635cc98548SSteven Rostedt * 645cc98548SSteven Rostedt * Here's some silly ASCII art. 655cc98548SSteven Rostedt * 665cc98548SSteven Rostedt * +------+ 675cc98548SSteven Rostedt * |reader| RING BUFFER 685cc98548SSteven Rostedt * |page | 695cc98548SSteven Rostedt * +------+ +---+ +---+ +---+ 705cc98548SSteven Rostedt * | |-->| |-->| | 715cc98548SSteven Rostedt * +---+ +---+ +---+ 725cc98548SSteven Rostedt * ^ | 735cc98548SSteven Rostedt * | | 745cc98548SSteven Rostedt * +---------------+ 755cc98548SSteven Rostedt * 765cc98548SSteven Rostedt * 775cc98548SSteven Rostedt * +------+ 785cc98548SSteven Rostedt * |reader| RING BUFFER 795cc98548SSteven Rostedt * |page |------------------v 805cc98548SSteven Rostedt * +------+ +---+ +---+ +---+ 815cc98548SSteven Rostedt * | |-->| |-->| | 825cc98548SSteven Rostedt * +---+ +---+ +---+ 835cc98548SSteven Rostedt * ^ | 845cc98548SSteven Rostedt * | | 855cc98548SSteven Rostedt * +---------------+ 865cc98548SSteven Rostedt * 875cc98548SSteven Rostedt * 885cc98548SSteven Rostedt * +------+ 895cc98548SSteven Rostedt * |reader| RING BUFFER 905cc98548SSteven Rostedt * |page |------------------v 915cc98548SSteven Rostedt * +------+ +---+ +---+ +---+ 925cc98548SSteven Rostedt * ^ | |-->| |-->| | 935cc98548SSteven Rostedt * | +---+ +---+ +---+ 945cc98548SSteven Rostedt * | | 955cc98548SSteven Rostedt * | | 965cc98548SSteven Rostedt * +------------------------------+ 975cc98548SSteven Rostedt * 985cc98548SSteven Rostedt * 995cc98548SSteven Rostedt * +------+ 1005cc98548SSteven Rostedt * |buffer| RING BUFFER 1015cc98548SSteven Rostedt * |page |------------------v 1025cc98548SSteven Rostedt * +------+ +---+ +---+ +---+ 1035cc98548SSteven Rostedt * ^ | | | |-->| | 1045cc98548SSteven Rostedt * | New +---+ +---+ +---+ 1055cc98548SSteven Rostedt * | Reader------^ | 1065cc98548SSteven Rostedt * | page | 1075cc98548SSteven Rostedt * +------------------------------+ 1085cc98548SSteven Rostedt * 1095cc98548SSteven Rostedt * 1105cc98548SSteven Rostedt * After we make this swap, the reader can hand this page off to the splice 1115cc98548SSteven Rostedt * code and be done with it. It can even allocate a new page if it needs to 1125cc98548SSteven Rostedt * and swap that into the ring buffer. 1135cc98548SSteven Rostedt * 1145cc98548SSteven Rostedt * We will be using cmpxchg soon to make all this lockless. 1155cc98548SSteven Rostedt * 1165cc98548SSteven Rostedt */ 1175cc98548SSteven Rostedt 118499e5470SSteven Rostedt /* Used for individual buffers (after the counter) */ 119499e5470SSteven Rostedt #define RB_BUFFER_OFF (1 << 20) 120499e5470SSteven Rostedt 121474d32b6SSteven Rostedt #define BUF_PAGE_HDR_SIZE offsetof(struct buffer_data_page, data) 122474d32b6SSteven Rostedt 123e3d6bf0aSSteven Rostedt #define RB_EVNT_HDR_SIZE (offsetof(struct ring_buffer_event, array)) 12467d34724SAndrew Morton #define RB_ALIGNMENT 4U 125334d4169SLai Jiangshan #define RB_MAX_SMALL_DATA (RB_ALIGNMENT * RINGBUF_TYPE_DATA_TYPE_LEN_MAX) 126c7b09308SSteven Rostedt #define RB_EVNT_MIN_SIZE 8U /* two 32bit words */ 127334d4169SLai Jiangshan 128649508f6SJames Hogan #ifndef CONFIG_HAVE_64BIT_ALIGNED_ACCESS 1292271048dSSteven Rostedt # define RB_FORCE_8BYTE_ALIGNMENT 0 1302271048dSSteven Rostedt # define RB_ARCH_ALIGNMENT RB_ALIGNMENT 1312271048dSSteven Rostedt #else 1322271048dSSteven Rostedt # define RB_FORCE_8BYTE_ALIGNMENT 1 1332271048dSSteven Rostedt # define RB_ARCH_ALIGNMENT 8U 1342271048dSSteven Rostedt #endif 1352271048dSSteven Rostedt 136649508f6SJames Hogan #define RB_ALIGN_DATA __aligned(RB_ARCH_ALIGNMENT) 137649508f6SJames Hogan 138334d4169SLai Jiangshan /* define RINGBUF_TYPE_DATA for 'case RINGBUF_TYPE_DATA:' */ 139334d4169SLai Jiangshan #define RINGBUF_TYPE_DATA 0 ... RINGBUF_TYPE_DATA_TYPE_LEN_MAX 1407a8e76a3SSteven Rostedt 1417a8e76a3SSteven Rostedt enum { 1427a8e76a3SSteven Rostedt RB_LEN_TIME_EXTEND = 8, 1437a8e76a3SSteven Rostedt RB_LEN_TIME_STAMP = 16, 1447a8e76a3SSteven Rostedt }; 1457a8e76a3SSteven Rostedt 14669d1b839SSteven Rostedt #define skip_time_extend(event) \ 14769d1b839SSteven Rostedt ((struct ring_buffer_event *)((char *)event + RB_LEN_TIME_EXTEND)) 14869d1b839SSteven Rostedt 1492d622719STom Zanussi static inline int rb_null_event(struct ring_buffer_event *event) 1502d622719STom Zanussi { 151a1863c21SSteven Rostedt return event->type_len == RINGBUF_TYPE_PADDING && !event->time_delta; 1522d622719STom Zanussi } 1532d622719STom Zanussi 1542d622719STom Zanussi static void rb_event_set_padding(struct ring_buffer_event *event) 1552d622719STom Zanussi { 156a1863c21SSteven Rostedt /* padding has a NULL time_delta */ 157334d4169SLai Jiangshan event->type_len = RINGBUF_TYPE_PADDING; 1582d622719STom Zanussi event->time_delta = 0; 1592d622719STom Zanussi } 1602d622719STom Zanussi 1612d622719STom Zanussi static unsigned 1622d622719STom Zanussi rb_event_data_length(struct ring_buffer_event *event) 1632d622719STom Zanussi { 1642d622719STom Zanussi unsigned length; 1652d622719STom Zanussi 166334d4169SLai Jiangshan if (event->type_len) 167334d4169SLai Jiangshan length = event->type_len * RB_ALIGNMENT; 1682d622719STom Zanussi else 1692d622719STom Zanussi length = event->array[0]; 1702d622719STom Zanussi return length + RB_EVNT_HDR_SIZE; 1712d622719STom Zanussi } 1722d622719STom Zanussi 17369d1b839SSteven Rostedt /* 17469d1b839SSteven Rostedt * Return the length of the given event. Will return 17569d1b839SSteven Rostedt * the length of the time extend if the event is a 17669d1b839SSteven Rostedt * time extend. 17769d1b839SSteven Rostedt */ 17869d1b839SSteven Rostedt static inline unsigned 1797a8e76a3SSteven Rostedt rb_event_length(struct ring_buffer_event *event) 1807a8e76a3SSteven Rostedt { 181334d4169SLai Jiangshan switch (event->type_len) { 1827a8e76a3SSteven Rostedt case RINGBUF_TYPE_PADDING: 1832d622719STom Zanussi if (rb_null_event(event)) 1847a8e76a3SSteven Rostedt /* undefined */ 1857a8e76a3SSteven Rostedt return -1; 186334d4169SLai Jiangshan return event->array[0] + RB_EVNT_HDR_SIZE; 1877a8e76a3SSteven Rostedt 1887a8e76a3SSteven Rostedt case RINGBUF_TYPE_TIME_EXTEND: 1897a8e76a3SSteven Rostedt return RB_LEN_TIME_EXTEND; 1907a8e76a3SSteven Rostedt 1917a8e76a3SSteven Rostedt case RINGBUF_TYPE_TIME_STAMP: 1927a8e76a3SSteven Rostedt return RB_LEN_TIME_STAMP; 1937a8e76a3SSteven Rostedt 1947a8e76a3SSteven Rostedt case RINGBUF_TYPE_DATA: 1952d622719STom Zanussi return rb_event_data_length(event); 1967a8e76a3SSteven Rostedt default: 1977a8e76a3SSteven Rostedt BUG(); 1987a8e76a3SSteven Rostedt } 1997a8e76a3SSteven Rostedt /* not hit */ 2007a8e76a3SSteven Rostedt return 0; 2017a8e76a3SSteven Rostedt } 2027a8e76a3SSteven Rostedt 20369d1b839SSteven Rostedt /* 20469d1b839SSteven Rostedt * Return total length of time extend and data, 20569d1b839SSteven Rostedt * or just the event length for all other events. 20669d1b839SSteven Rostedt */ 20769d1b839SSteven Rostedt static inline unsigned 20869d1b839SSteven Rostedt rb_event_ts_length(struct ring_buffer_event *event) 20969d1b839SSteven Rostedt { 21069d1b839SSteven Rostedt unsigned len = 0; 21169d1b839SSteven Rostedt 21269d1b839SSteven Rostedt if (event->type_len == RINGBUF_TYPE_TIME_EXTEND) { 21369d1b839SSteven Rostedt /* time extends include the data event after it */ 21469d1b839SSteven Rostedt len = RB_LEN_TIME_EXTEND; 21569d1b839SSteven Rostedt event = skip_time_extend(event); 21669d1b839SSteven Rostedt } 21769d1b839SSteven Rostedt return len + rb_event_length(event); 21869d1b839SSteven Rostedt } 21969d1b839SSteven Rostedt 2207a8e76a3SSteven Rostedt /** 2217a8e76a3SSteven Rostedt * ring_buffer_event_length - return the length of the event 2227a8e76a3SSteven Rostedt * @event: the event to get the length of 22369d1b839SSteven Rostedt * 22469d1b839SSteven Rostedt * Returns the size of the data load of a data event. 22569d1b839SSteven Rostedt * If the event is something other than a data event, it 22669d1b839SSteven Rostedt * returns the size of the event itself. With the exception 22769d1b839SSteven Rostedt * of a TIME EXTEND, where it still returns the size of the 22869d1b839SSteven Rostedt * data load of the data event after it. 2297a8e76a3SSteven Rostedt */ 2307a8e76a3SSteven Rostedt unsigned ring_buffer_event_length(struct ring_buffer_event *event) 2317a8e76a3SSteven Rostedt { 23269d1b839SSteven Rostedt unsigned length; 23369d1b839SSteven Rostedt 23469d1b839SSteven Rostedt if (event->type_len == RINGBUF_TYPE_TIME_EXTEND) 23569d1b839SSteven Rostedt event = skip_time_extend(event); 23669d1b839SSteven Rostedt 23769d1b839SSteven Rostedt length = rb_event_length(event); 238334d4169SLai Jiangshan if (event->type_len > RINGBUF_TYPE_DATA_TYPE_LEN_MAX) 239465634adSRobert Richter return length; 240465634adSRobert Richter length -= RB_EVNT_HDR_SIZE; 241465634adSRobert Richter if (length > RB_MAX_SMALL_DATA + sizeof(event->array[0])) 242465634adSRobert Richter length -= sizeof(event->array[0]); 243465634adSRobert Richter return length; 2447a8e76a3SSteven Rostedt } 245c4f50183SRobert Richter EXPORT_SYMBOL_GPL(ring_buffer_event_length); 2467a8e76a3SSteven Rostedt 2477a8e76a3SSteven Rostedt /* inline for ring buffer fast paths */ 248929ddbf3SSteven Rostedt (Red Hat) static __always_inline void * 2497a8e76a3SSteven Rostedt rb_event_data(struct ring_buffer_event *event) 2507a8e76a3SSteven Rostedt { 25169d1b839SSteven Rostedt if (event->type_len == RINGBUF_TYPE_TIME_EXTEND) 25269d1b839SSteven Rostedt event = skip_time_extend(event); 253334d4169SLai Jiangshan BUG_ON(event->type_len > RINGBUF_TYPE_DATA_TYPE_LEN_MAX); 2547a8e76a3SSteven Rostedt /* If length is in len field, then array[0] has the data */ 255334d4169SLai Jiangshan if (event->type_len) 2567a8e76a3SSteven Rostedt return (void *)&event->array[0]; 2577a8e76a3SSteven Rostedt /* Otherwise length is in array[0] and array[1] has the data */ 2587a8e76a3SSteven Rostedt return (void *)&event->array[1]; 2597a8e76a3SSteven Rostedt } 2607a8e76a3SSteven Rostedt 2617a8e76a3SSteven Rostedt /** 2627a8e76a3SSteven Rostedt * ring_buffer_event_data - return the data of the event 2637a8e76a3SSteven Rostedt * @event: the event to get the data from 2647a8e76a3SSteven Rostedt */ 2657a8e76a3SSteven Rostedt void *ring_buffer_event_data(struct ring_buffer_event *event) 2667a8e76a3SSteven Rostedt { 2677a8e76a3SSteven Rostedt return rb_event_data(event); 2687a8e76a3SSteven Rostedt } 269c4f50183SRobert Richter EXPORT_SYMBOL_GPL(ring_buffer_event_data); 2707a8e76a3SSteven Rostedt 2717a8e76a3SSteven Rostedt #define for_each_buffer_cpu(buffer, cpu) \ 2729e01c1b7SRusty Russell for_each_cpu(cpu, buffer->cpumask) 2737a8e76a3SSteven Rostedt 2747a8e76a3SSteven Rostedt #define TS_SHIFT 27 2757a8e76a3SSteven Rostedt #define TS_MASK ((1ULL << TS_SHIFT) - 1) 2767a8e76a3SSteven Rostedt #define TS_DELTA_TEST (~TS_MASK) 2777a8e76a3SSteven Rostedt 27866a8cb95SSteven Rostedt /* Flag when events were overwritten */ 27966a8cb95SSteven Rostedt #define RB_MISSED_EVENTS (1 << 31) 280ff0ff84aSSteven Rostedt /* Missed count stored at end */ 281ff0ff84aSSteven Rostedt #define RB_MISSED_STORED (1 << 30) 28266a8cb95SSteven Rostedt 28345d8b80cSSteven Rostedt (VMware) #define RB_MISSED_FLAGS (RB_MISSED_EVENTS|RB_MISSED_STORED) 28445d8b80cSSteven Rostedt (VMware) 285abc9b56dSSteven Rostedt struct buffer_data_page { 2867a8e76a3SSteven Rostedt u64 time_stamp; /* page time stamp */ 287c3706f00SWenji Huang local_t commit; /* write committed index */ 288649508f6SJames Hogan unsigned char data[] RB_ALIGN_DATA; /* data of buffer page */ 289abc9b56dSSteven Rostedt }; 290abc9b56dSSteven Rostedt 29177ae365eSSteven Rostedt /* 29277ae365eSSteven Rostedt * Note, the buffer_page list must be first. The buffer pages 29377ae365eSSteven Rostedt * are allocated in cache lines, which means that each buffer 29477ae365eSSteven Rostedt * page will be at the beginning of a cache line, and thus 29577ae365eSSteven Rostedt * the least significant bits will be zero. We use this to 29677ae365eSSteven Rostedt * add flags in the list struct pointers, to make the ring buffer 29777ae365eSSteven Rostedt * lockless. 29877ae365eSSteven Rostedt */ 299abc9b56dSSteven Rostedt struct buffer_page { 300778c55d4SSteven Rostedt struct list_head list; /* list of buffer pages */ 301abc9b56dSSteven Rostedt local_t write; /* index for next write */ 3026f807acdSSteven Rostedt unsigned read; /* index for next read */ 303778c55d4SSteven Rostedt local_t entries; /* entries on this page */ 304ff0ff84aSSteven Rostedt unsigned long real_end; /* real end of data */ 305abc9b56dSSteven Rostedt struct buffer_data_page *page; /* Actual data page */ 3067a8e76a3SSteven Rostedt }; 3077a8e76a3SSteven Rostedt 30877ae365eSSteven Rostedt /* 30977ae365eSSteven Rostedt * The buffer page counters, write and entries, must be reset 31077ae365eSSteven Rostedt * atomically when crossing page boundaries. To synchronize this 31177ae365eSSteven Rostedt * update, two counters are inserted into the number. One is 31277ae365eSSteven Rostedt * the actual counter for the write position or count on the page. 31377ae365eSSteven Rostedt * 31477ae365eSSteven Rostedt * The other is a counter of updaters. Before an update happens 31577ae365eSSteven Rostedt * the update partition of the counter is incremented. This will 31677ae365eSSteven Rostedt * allow the updater to update the counter atomically. 31777ae365eSSteven Rostedt * 31877ae365eSSteven Rostedt * The counter is 20 bits, and the state data is 12. 31977ae365eSSteven Rostedt */ 32077ae365eSSteven Rostedt #define RB_WRITE_MASK 0xfffff 32177ae365eSSteven Rostedt #define RB_WRITE_INTCNT (1 << 20) 32277ae365eSSteven Rostedt 323044fa782SSteven Rostedt static void rb_init_page(struct buffer_data_page *bpage) 324abc9b56dSSteven Rostedt { 325044fa782SSteven Rostedt local_set(&bpage->commit, 0); 326abc9b56dSSteven Rostedt } 327abc9b56dSSteven Rostedt 328474d32b6SSteven Rostedt /** 329474d32b6SSteven Rostedt * ring_buffer_page_len - the size of data on the page. 330474d32b6SSteven Rostedt * @page: The page to read 331474d32b6SSteven Rostedt * 332474d32b6SSteven Rostedt * Returns the amount of data on the page, including buffer page header. 333474d32b6SSteven Rostedt */ 334ef7a4a16SSteven Rostedt size_t ring_buffer_page_len(void *page) 335ef7a4a16SSteven Rostedt { 33645d8b80cSSteven Rostedt (VMware) struct buffer_data_page *bpage = page; 33745d8b80cSSteven Rostedt (VMware) 33845d8b80cSSteven Rostedt (VMware) return (local_read(&bpage->commit) & ~RB_MISSED_FLAGS) 339474d32b6SSteven Rostedt + BUF_PAGE_HDR_SIZE; 340ef7a4a16SSteven Rostedt } 341ef7a4a16SSteven Rostedt 3427a8e76a3SSteven Rostedt /* 343ed56829cSSteven Rostedt * Also stolen from mm/slob.c. Thanks to Mathieu Desnoyers for pointing 344ed56829cSSteven Rostedt * this issue out. 345ed56829cSSteven Rostedt */ 34634a148bfSAndrew Morton static void free_buffer_page(struct buffer_page *bpage) 347ed56829cSSteven Rostedt { 3486ae2a076SSteven Rostedt free_page((unsigned long)bpage->page); 349e4c2ce82SSteven Rostedt kfree(bpage); 350ed56829cSSteven Rostedt } 351ed56829cSSteven Rostedt 352ed56829cSSteven Rostedt /* 3537a8e76a3SSteven Rostedt * We need to fit the time_stamp delta into 27 bits. 3547a8e76a3SSteven Rostedt */ 3557a8e76a3SSteven Rostedt static inline int test_time_stamp(u64 delta) 3567a8e76a3SSteven Rostedt { 3577a8e76a3SSteven Rostedt if (delta & TS_DELTA_TEST) 3587a8e76a3SSteven Rostedt return 1; 3597a8e76a3SSteven Rostedt return 0; 3607a8e76a3SSteven Rostedt } 3617a8e76a3SSteven Rostedt 362474d32b6SSteven Rostedt #define BUF_PAGE_SIZE (PAGE_SIZE - BUF_PAGE_HDR_SIZE) 3637a8e76a3SSteven Rostedt 364be957c44SSteven Rostedt /* Max payload is BUF_PAGE_SIZE - header (8bytes) */ 365be957c44SSteven Rostedt #define BUF_MAX_DATA_SIZE (BUF_PAGE_SIZE - (sizeof(u32) * 2)) 366be957c44SSteven Rostedt 367d1b182a8SSteven Rostedt int ring_buffer_print_page_header(struct trace_seq *s) 368d1b182a8SSteven Rostedt { 369d1b182a8SSteven Rostedt struct buffer_data_page field; 370d1b182a8SSteven Rostedt 371c0cd93aaSSteven Rostedt (Red Hat) trace_seq_printf(s, "\tfield: u64 timestamp;\t" 37226a50744STom Zanussi "offset:0;\tsize:%u;\tsigned:%u;\n", 37326a50744STom Zanussi (unsigned int)sizeof(field.time_stamp), 37426a50744STom Zanussi (unsigned int)is_signed_type(u64)); 375d1b182a8SSteven Rostedt 376c0cd93aaSSteven Rostedt (Red Hat) trace_seq_printf(s, "\tfield: local_t commit;\t" 37726a50744STom Zanussi "offset:%u;\tsize:%u;\tsigned:%u;\n", 378d1b182a8SSteven Rostedt (unsigned int)offsetof(typeof(field), commit), 37926a50744STom Zanussi (unsigned int)sizeof(field.commit), 38026a50744STom Zanussi (unsigned int)is_signed_type(long)); 381d1b182a8SSteven Rostedt 382c0cd93aaSSteven Rostedt (Red Hat) trace_seq_printf(s, "\tfield: int overwrite;\t" 38366a8cb95SSteven Rostedt "offset:%u;\tsize:%u;\tsigned:%u;\n", 38466a8cb95SSteven Rostedt (unsigned int)offsetof(typeof(field), commit), 38566a8cb95SSteven Rostedt 1, 38666a8cb95SSteven Rostedt (unsigned int)is_signed_type(long)); 38766a8cb95SSteven Rostedt 388c0cd93aaSSteven Rostedt (Red Hat) trace_seq_printf(s, "\tfield: char data;\t" 38926a50744STom Zanussi "offset:%u;\tsize:%u;\tsigned:%u;\n", 390d1b182a8SSteven Rostedt (unsigned int)offsetof(typeof(field), data), 39126a50744STom Zanussi (unsigned int)BUF_PAGE_SIZE, 39226a50744STom Zanussi (unsigned int)is_signed_type(char)); 393d1b182a8SSteven Rostedt 394c0cd93aaSSteven Rostedt (Red Hat) return !trace_seq_has_overflowed(s); 395d1b182a8SSteven Rostedt } 396d1b182a8SSteven Rostedt 39715693458SSteven Rostedt (Red Hat) struct rb_irq_work { 39815693458SSteven Rostedt (Red Hat) struct irq_work work; 39915693458SSteven Rostedt (Red Hat) wait_queue_head_t waiters; 4001e0d6714SSteven Rostedt (Red Hat) wait_queue_head_t full_waiters; 40115693458SSteven Rostedt (Red Hat) bool waiters_pending; 4021e0d6714SSteven Rostedt (Red Hat) bool full_waiters_pending; 4031e0d6714SSteven Rostedt (Red Hat) bool wakeup_full; 40415693458SSteven Rostedt (Red Hat) }; 40515693458SSteven Rostedt (Red Hat) 4067a8e76a3SSteven Rostedt /* 407fcc742eaSSteven Rostedt (Red Hat) * Structure to hold event state and handle nested events. 408fcc742eaSSteven Rostedt (Red Hat) */ 409fcc742eaSSteven Rostedt (Red Hat) struct rb_event_info { 410fcc742eaSSteven Rostedt (Red Hat) u64 ts; 411fcc742eaSSteven Rostedt (Red Hat) u64 delta; 412fcc742eaSSteven Rostedt (Red Hat) unsigned long length; 413fcc742eaSSteven Rostedt (Red Hat) struct buffer_page *tail_page; 414fcc742eaSSteven Rostedt (Red Hat) int add_timestamp; 415fcc742eaSSteven Rostedt (Red Hat) }; 416fcc742eaSSteven Rostedt (Red Hat) 417fcc742eaSSteven Rostedt (Red Hat) /* 418a497adb4SSteven Rostedt (Red Hat) * Used for which event context the event is in. 419a497adb4SSteven Rostedt (Red Hat) * NMI = 0 420a497adb4SSteven Rostedt (Red Hat) * IRQ = 1 421a497adb4SSteven Rostedt (Red Hat) * SOFTIRQ = 2 422a497adb4SSteven Rostedt (Red Hat) * NORMAL = 3 423a497adb4SSteven Rostedt (Red Hat) * 424a497adb4SSteven Rostedt (Red Hat) * See trace_recursive_lock() comment below for more details. 425a497adb4SSteven Rostedt (Red Hat) */ 426a497adb4SSteven Rostedt (Red Hat) enum { 427a497adb4SSteven Rostedt (Red Hat) RB_CTX_NMI, 428a497adb4SSteven Rostedt (Red Hat) RB_CTX_IRQ, 429a497adb4SSteven Rostedt (Red Hat) RB_CTX_SOFTIRQ, 430a497adb4SSteven Rostedt (Red Hat) RB_CTX_NORMAL, 431a497adb4SSteven Rostedt (Red Hat) RB_CTX_MAX 432a497adb4SSteven Rostedt (Red Hat) }; 433a497adb4SSteven Rostedt (Red Hat) 434a497adb4SSteven Rostedt (Red Hat) /* 4357a8e76a3SSteven Rostedt * head_page == tail_page && head == tail then buffer is empty. 4367a8e76a3SSteven Rostedt */ 4377a8e76a3SSteven Rostedt struct ring_buffer_per_cpu { 4387a8e76a3SSteven Rostedt int cpu; 439985023deSRichard Kennedy atomic_t record_disabled; 4407a8e76a3SSteven Rostedt struct ring_buffer *buffer; 4415389f6faSThomas Gleixner raw_spinlock_t reader_lock; /* serialize readers */ 442445c8951SThomas Gleixner arch_spinlock_t lock; 4437a8e76a3SSteven Rostedt struct lock_class_key lock_key; 44473a757e6SSteven Rostedt (VMware) struct buffer_data_page *free_page; 4459b94a8fbSSteven Rostedt (Red Hat) unsigned long nr_pages; 44658a09ec6SSteven Rostedt (Red Hat) unsigned int current_context; 4473adc54faSSteven Rostedt struct list_head *pages; 4486f807acdSSteven Rostedt struct buffer_page *head_page; /* read from head */ 4496f807acdSSteven Rostedt struct buffer_page *tail_page; /* write to tail */ 450c3706f00SWenji Huang struct buffer_page *commit_page; /* committed pages */ 451d769041fSSteven Rostedt struct buffer_page *reader_page; 45266a8cb95SSteven Rostedt unsigned long lost_events; 45366a8cb95SSteven Rostedt unsigned long last_overrun; 454c64e148aSVaibhav Nagarnaik local_t entries_bytes; 455e4906effSSteven Rostedt local_t entries; 456884bfe89SSlava Pestov local_t overrun; 457884bfe89SSlava Pestov local_t commit_overrun; 458884bfe89SSlava Pestov local_t dropped_events; 459fa743953SSteven Rostedt local_t committing; 460fa743953SSteven Rostedt local_t commits; 46177ae365eSSteven Rostedt unsigned long read; 462c64e148aSVaibhav Nagarnaik unsigned long read_bytes; 4637a8e76a3SSteven Rostedt u64 write_stamp; 4647a8e76a3SSteven Rostedt u64 read_stamp; 465438ced17SVaibhav Nagarnaik /* ring buffer pages to update, > 0 to add, < 0 to remove */ 4669b94a8fbSSteven Rostedt (Red Hat) long nr_pages_to_update; 467438ced17SVaibhav Nagarnaik struct list_head new_pages; /* new pages to add */ 46883f40318SVaibhav Nagarnaik struct work_struct update_pages_work; 46905fdd70dSVaibhav Nagarnaik struct completion update_done; 47015693458SSteven Rostedt (Red Hat) 47115693458SSteven Rostedt (Red Hat) struct rb_irq_work irq_work; 4727a8e76a3SSteven Rostedt }; 4737a8e76a3SSteven Rostedt 4747a8e76a3SSteven Rostedt struct ring_buffer { 4757a8e76a3SSteven Rostedt unsigned flags; 4767a8e76a3SSteven Rostedt int cpus; 4777a8e76a3SSteven Rostedt atomic_t record_disabled; 47883f40318SVaibhav Nagarnaik atomic_t resize_disabled; 47900f62f61SArnaldo Carvalho de Melo cpumask_var_t cpumask; 4807a8e76a3SSteven Rostedt 4811f8a6a10SPeter Zijlstra struct lock_class_key *reader_lock_key; 4821f8a6a10SPeter Zijlstra 4837a8e76a3SSteven Rostedt struct mutex mutex; 4847a8e76a3SSteven Rostedt 4857a8e76a3SSteven Rostedt struct ring_buffer_per_cpu **buffers; 486554f786eSSteven Rostedt 487b32614c0SSebastian Andrzej Siewior struct hlist_node node; 48837886f6aSSteven Rostedt u64 (*clock)(void); 48915693458SSteven Rostedt (Red Hat) 49015693458SSteven Rostedt (Red Hat) struct rb_irq_work irq_work; 4917a8e76a3SSteven Rostedt }; 4927a8e76a3SSteven Rostedt 4937a8e76a3SSteven Rostedt struct ring_buffer_iter { 4947a8e76a3SSteven Rostedt struct ring_buffer_per_cpu *cpu_buffer; 4957a8e76a3SSteven Rostedt unsigned long head; 4967a8e76a3SSteven Rostedt struct buffer_page *head_page; 497492a74f4SSteven Rostedt struct buffer_page *cache_reader_page; 498492a74f4SSteven Rostedt unsigned long cache_read; 4997a8e76a3SSteven Rostedt u64 read_stamp; 5007a8e76a3SSteven Rostedt }; 5017a8e76a3SSteven Rostedt 50215693458SSteven Rostedt (Red Hat) /* 50315693458SSteven Rostedt (Red Hat) * rb_wake_up_waiters - wake up tasks waiting for ring buffer input 50415693458SSteven Rostedt (Red Hat) * 50515693458SSteven Rostedt (Red Hat) * Schedules a delayed work to wake up any task that is blocked on the 50615693458SSteven Rostedt (Red Hat) * ring buffer waiters queue. 50715693458SSteven Rostedt (Red Hat) */ 50815693458SSteven Rostedt (Red Hat) static void rb_wake_up_waiters(struct irq_work *work) 50915693458SSteven Rostedt (Red Hat) { 51015693458SSteven Rostedt (Red Hat) struct rb_irq_work *rbwork = container_of(work, struct rb_irq_work, work); 51115693458SSteven Rostedt (Red Hat) 51215693458SSteven Rostedt (Red Hat) wake_up_all(&rbwork->waiters); 5131e0d6714SSteven Rostedt (Red Hat) if (rbwork->wakeup_full) { 5141e0d6714SSteven Rostedt (Red Hat) rbwork->wakeup_full = false; 5151e0d6714SSteven Rostedt (Red Hat) wake_up_all(&rbwork->full_waiters); 5161e0d6714SSteven Rostedt (Red Hat) } 51715693458SSteven Rostedt (Red Hat) } 51815693458SSteven Rostedt (Red Hat) 51915693458SSteven Rostedt (Red Hat) /** 52015693458SSteven Rostedt (Red Hat) * ring_buffer_wait - wait for input to the ring buffer 52115693458SSteven Rostedt (Red Hat) * @buffer: buffer to wait on 52215693458SSteven Rostedt (Red Hat) * @cpu: the cpu buffer to wait on 523e30f53aaSRabin Vincent * @full: wait until a full page is available, if @cpu != RING_BUFFER_ALL_CPUS 52415693458SSteven Rostedt (Red Hat) * 52515693458SSteven Rostedt (Red Hat) * If @cpu == RING_BUFFER_ALL_CPUS then the task will wake up as soon 52615693458SSteven Rostedt (Red Hat) * as data is added to any of the @buffer's cpu buffers. Otherwise 52715693458SSteven Rostedt (Red Hat) * it will wait for data to be added to a specific cpu buffer. 52815693458SSteven Rostedt (Red Hat) */ 529e30f53aaSRabin Vincent int ring_buffer_wait(struct ring_buffer *buffer, int cpu, bool full) 53015693458SSteven Rostedt (Red Hat) { 531e30f53aaSRabin Vincent struct ring_buffer_per_cpu *uninitialized_var(cpu_buffer); 53215693458SSteven Rostedt (Red Hat) DEFINE_WAIT(wait); 53315693458SSteven Rostedt (Red Hat) struct rb_irq_work *work; 534e30f53aaSRabin Vincent int ret = 0; 53515693458SSteven Rostedt (Red Hat) 53615693458SSteven Rostedt (Red Hat) /* 53715693458SSteven Rostedt (Red Hat) * Depending on what the caller is waiting for, either any 53815693458SSteven Rostedt (Red Hat) * data in any cpu buffer, or a specific buffer, put the 53915693458SSteven Rostedt (Red Hat) * caller on the appropriate wait queue. 54015693458SSteven Rostedt (Red Hat) */ 5411e0d6714SSteven Rostedt (Red Hat) if (cpu == RING_BUFFER_ALL_CPUS) { 54215693458SSteven Rostedt (Red Hat) work = &buffer->irq_work; 5431e0d6714SSteven Rostedt (Red Hat) /* Full only makes sense on per cpu reads */ 5441e0d6714SSteven Rostedt (Red Hat) full = false; 5451e0d6714SSteven Rostedt (Red Hat) } else { 5468b8b3683SSteven Rostedt (Red Hat) if (!cpumask_test_cpu(cpu, buffer->cpumask)) 5478b8b3683SSteven Rostedt (Red Hat) return -ENODEV; 54815693458SSteven Rostedt (Red Hat) cpu_buffer = buffer->buffers[cpu]; 54915693458SSteven Rostedt (Red Hat) work = &cpu_buffer->irq_work; 55015693458SSteven Rostedt (Red Hat) } 55115693458SSteven Rostedt (Red Hat) 55215693458SSteven Rostedt (Red Hat) 553e30f53aaSRabin Vincent while (true) { 5541e0d6714SSteven Rostedt (Red Hat) if (full) 5551e0d6714SSteven Rostedt (Red Hat) prepare_to_wait(&work->full_waiters, &wait, TASK_INTERRUPTIBLE); 5561e0d6714SSteven Rostedt (Red Hat) else 55715693458SSteven Rostedt (Red Hat) prepare_to_wait(&work->waiters, &wait, TASK_INTERRUPTIBLE); 55815693458SSteven Rostedt (Red Hat) 55915693458SSteven Rostedt (Red Hat) /* 56015693458SSteven Rostedt (Red Hat) * The events can happen in critical sections where 56115693458SSteven Rostedt (Red Hat) * checking a work queue can cause deadlocks. 56215693458SSteven Rostedt (Red Hat) * After adding a task to the queue, this flag is set 56315693458SSteven Rostedt (Red Hat) * only to notify events to try to wake up the queue 56415693458SSteven Rostedt (Red Hat) * using irq_work. 56515693458SSteven Rostedt (Red Hat) * 56615693458SSteven Rostedt (Red Hat) * We don't clear it even if the buffer is no longer 56715693458SSteven Rostedt (Red Hat) * empty. The flag only causes the next event to run 56815693458SSteven Rostedt (Red Hat) * irq_work to do the work queue wake up. The worse 56915693458SSteven Rostedt (Red Hat) * that can happen if we race with !trace_empty() is that 57015693458SSteven Rostedt (Red Hat) * an event will cause an irq_work to try to wake up 57115693458SSteven Rostedt (Red Hat) * an empty queue. 57215693458SSteven Rostedt (Red Hat) * 57315693458SSteven Rostedt (Red Hat) * There's no reason to protect this flag either, as 57415693458SSteven Rostedt (Red Hat) * the work queue and irq_work logic will do the necessary 57515693458SSteven Rostedt (Red Hat) * synchronization for the wake ups. The only thing 57615693458SSteven Rostedt (Red Hat) * that is necessary is that the wake up happens after 57715693458SSteven Rostedt (Red Hat) * a task has been queued. It's OK for spurious wake ups. 57815693458SSteven Rostedt (Red Hat) */ 5791e0d6714SSteven Rostedt (Red Hat) if (full) 5801e0d6714SSteven Rostedt (Red Hat) work->full_waiters_pending = true; 5811e0d6714SSteven Rostedt (Red Hat) else 58215693458SSteven Rostedt (Red Hat) work->waiters_pending = true; 58315693458SSteven Rostedt (Red Hat) 584e30f53aaSRabin Vincent if (signal_pending(current)) { 585e30f53aaSRabin Vincent ret = -EINTR; 586e30f53aaSRabin Vincent break; 587e30f53aaSRabin Vincent } 588e30f53aaSRabin Vincent 589e30f53aaSRabin Vincent if (cpu == RING_BUFFER_ALL_CPUS && !ring_buffer_empty(buffer)) 590e30f53aaSRabin Vincent break; 591e30f53aaSRabin Vincent 592e30f53aaSRabin Vincent if (cpu != RING_BUFFER_ALL_CPUS && 593e30f53aaSRabin Vincent !ring_buffer_empty_cpu(buffer, cpu)) { 594e30f53aaSRabin Vincent unsigned long flags; 595e30f53aaSRabin Vincent bool pagebusy; 596e30f53aaSRabin Vincent 597e30f53aaSRabin Vincent if (!full) 598e30f53aaSRabin Vincent break; 599e30f53aaSRabin Vincent 600e30f53aaSRabin Vincent raw_spin_lock_irqsave(&cpu_buffer->reader_lock, flags); 601e30f53aaSRabin Vincent pagebusy = cpu_buffer->reader_page == cpu_buffer->commit_page; 602e30f53aaSRabin Vincent raw_spin_unlock_irqrestore(&cpu_buffer->reader_lock, flags); 603e30f53aaSRabin Vincent 604e30f53aaSRabin Vincent if (!pagebusy) 605e30f53aaSRabin Vincent break; 606e30f53aaSRabin Vincent } 607e30f53aaSRabin Vincent 60815693458SSteven Rostedt (Red Hat) schedule(); 609e30f53aaSRabin Vincent } 61015693458SSteven Rostedt (Red Hat) 6111e0d6714SSteven Rostedt (Red Hat) if (full) 6121e0d6714SSteven Rostedt (Red Hat) finish_wait(&work->full_waiters, &wait); 6131e0d6714SSteven Rostedt (Red Hat) else 61415693458SSteven Rostedt (Red Hat) finish_wait(&work->waiters, &wait); 615e30f53aaSRabin Vincent 616e30f53aaSRabin Vincent return ret; 61715693458SSteven Rostedt (Red Hat) } 61815693458SSteven Rostedt (Red Hat) 61915693458SSteven Rostedt (Red Hat) /** 62015693458SSteven Rostedt (Red Hat) * ring_buffer_poll_wait - poll on buffer input 62115693458SSteven Rostedt (Red Hat) * @buffer: buffer to wait on 62215693458SSteven Rostedt (Red Hat) * @cpu: the cpu buffer to wait on 62315693458SSteven Rostedt (Red Hat) * @filp: the file descriptor 62415693458SSteven Rostedt (Red Hat) * @poll_table: The poll descriptor 62515693458SSteven Rostedt (Red Hat) * 62615693458SSteven Rostedt (Red Hat) * If @cpu == RING_BUFFER_ALL_CPUS then the task will wake up as soon 62715693458SSteven Rostedt (Red Hat) * as data is added to any of the @buffer's cpu buffers. Otherwise 62815693458SSteven Rostedt (Red Hat) * it will wait for data to be added to a specific cpu buffer. 62915693458SSteven Rostedt (Red Hat) * 63015693458SSteven Rostedt (Red Hat) * Returns POLLIN | POLLRDNORM if data exists in the buffers, 63115693458SSteven Rostedt (Red Hat) * zero otherwise. 63215693458SSteven Rostedt (Red Hat) */ 63315693458SSteven Rostedt (Red Hat) int ring_buffer_poll_wait(struct ring_buffer *buffer, int cpu, 63415693458SSteven Rostedt (Red Hat) struct file *filp, poll_table *poll_table) 63515693458SSteven Rostedt (Red Hat) { 63615693458SSteven Rostedt (Red Hat) struct ring_buffer_per_cpu *cpu_buffer; 63715693458SSteven Rostedt (Red Hat) struct rb_irq_work *work; 63815693458SSteven Rostedt (Red Hat) 63915693458SSteven Rostedt (Red Hat) if (cpu == RING_BUFFER_ALL_CPUS) 64015693458SSteven Rostedt (Red Hat) work = &buffer->irq_work; 64115693458SSteven Rostedt (Red Hat) else { 6426721cb60SSteven Rostedt (Red Hat) if (!cpumask_test_cpu(cpu, buffer->cpumask)) 6436721cb60SSteven Rostedt (Red Hat) return -EINVAL; 6446721cb60SSteven Rostedt (Red Hat) 64515693458SSteven Rostedt (Red Hat) cpu_buffer = buffer->buffers[cpu]; 64615693458SSteven Rostedt (Red Hat) work = &cpu_buffer->irq_work; 64715693458SSteven Rostedt (Red Hat) } 64815693458SSteven Rostedt (Red Hat) 64915693458SSteven Rostedt (Red Hat) poll_wait(filp, &work->waiters, poll_table); 6504ce97dbfSJosef Bacik work->waiters_pending = true; 6514ce97dbfSJosef Bacik /* 6524ce97dbfSJosef Bacik * There's a tight race between setting the waiters_pending and 6534ce97dbfSJosef Bacik * checking if the ring buffer is empty. Once the waiters_pending bit 6544ce97dbfSJosef Bacik * is set, the next event will wake the task up, but we can get stuck 6554ce97dbfSJosef Bacik * if there's only a single event in. 6564ce97dbfSJosef Bacik * 6574ce97dbfSJosef Bacik * FIXME: Ideally, we need a memory barrier on the writer side as well, 6584ce97dbfSJosef Bacik * but adding a memory barrier to all events will cause too much of a 6594ce97dbfSJosef Bacik * performance hit in the fast path. We only need a memory barrier when 6604ce97dbfSJosef Bacik * the buffer goes from empty to having content. But as this race is 6614ce97dbfSJosef Bacik * extremely small, and it's not a problem if another event comes in, we 6624ce97dbfSJosef Bacik * will fix it later. 6634ce97dbfSJosef Bacik */ 6644ce97dbfSJosef Bacik smp_mb(); 66515693458SSteven Rostedt (Red Hat) 66615693458SSteven Rostedt (Red Hat) if ((cpu == RING_BUFFER_ALL_CPUS && !ring_buffer_empty(buffer)) || 66715693458SSteven Rostedt (Red Hat) (cpu != RING_BUFFER_ALL_CPUS && !ring_buffer_empty_cpu(buffer, cpu))) 66815693458SSteven Rostedt (Red Hat) return POLLIN | POLLRDNORM; 66915693458SSteven Rostedt (Red Hat) return 0; 67015693458SSteven Rostedt (Red Hat) } 67115693458SSteven Rostedt (Red Hat) 672f536aafcSSteven Rostedt /* buffer may be either ring_buffer or ring_buffer_per_cpu */ 673077c5407SSteven Rostedt #define RB_WARN_ON(b, cond) \ 6743e89c7bbSSteven Rostedt ({ \ 6753e89c7bbSSteven Rostedt int _____ret = unlikely(cond); \ 6763e89c7bbSSteven Rostedt if (_____ret) { \ 677077c5407SSteven Rostedt if (__same_type(*(b), struct ring_buffer_per_cpu)) { \ 678077c5407SSteven Rostedt struct ring_buffer_per_cpu *__b = \ 679077c5407SSteven Rostedt (void *)b; \ 680077c5407SSteven Rostedt atomic_inc(&__b->buffer->record_disabled); \ 681077c5407SSteven Rostedt } else \ 682077c5407SSteven Rostedt atomic_inc(&b->record_disabled); \ 683bf41a158SSteven Rostedt WARN_ON(1); \ 684bf41a158SSteven Rostedt } \ 6853e89c7bbSSteven Rostedt _____ret; \ 6863e89c7bbSSteven Rostedt }) 687f536aafcSSteven Rostedt 68837886f6aSSteven Rostedt /* Up this if you want to test the TIME_EXTENTS and normalization */ 68937886f6aSSteven Rostedt #define DEBUG_SHIFT 0 69037886f6aSSteven Rostedt 6916d3f1e12SJiri Olsa static inline u64 rb_time_stamp(struct ring_buffer *buffer) 69288eb0125SSteven Rostedt { 69388eb0125SSteven Rostedt /* shift to debug/test normalization and TIME_EXTENTS */ 69488eb0125SSteven Rostedt return buffer->clock() << DEBUG_SHIFT; 69588eb0125SSteven Rostedt } 69688eb0125SSteven Rostedt 69737886f6aSSteven Rostedt u64 ring_buffer_time_stamp(struct ring_buffer *buffer, int cpu) 69837886f6aSSteven Rostedt { 69937886f6aSSteven Rostedt u64 time; 70037886f6aSSteven Rostedt 70137886f6aSSteven Rostedt preempt_disable_notrace(); 7026d3f1e12SJiri Olsa time = rb_time_stamp(buffer); 70337886f6aSSteven Rostedt preempt_enable_no_resched_notrace(); 70437886f6aSSteven Rostedt 70537886f6aSSteven Rostedt return time; 70637886f6aSSteven Rostedt } 70737886f6aSSteven Rostedt EXPORT_SYMBOL_GPL(ring_buffer_time_stamp); 70837886f6aSSteven Rostedt 70937886f6aSSteven Rostedt void ring_buffer_normalize_time_stamp(struct ring_buffer *buffer, 71037886f6aSSteven Rostedt int cpu, u64 *ts) 71137886f6aSSteven Rostedt { 71237886f6aSSteven Rostedt /* Just stupid testing the normalize function and deltas */ 71337886f6aSSteven Rostedt *ts >>= DEBUG_SHIFT; 71437886f6aSSteven Rostedt } 71537886f6aSSteven Rostedt EXPORT_SYMBOL_GPL(ring_buffer_normalize_time_stamp); 71637886f6aSSteven Rostedt 71777ae365eSSteven Rostedt /* 71877ae365eSSteven Rostedt * Making the ring buffer lockless makes things tricky. 71977ae365eSSteven Rostedt * Although writes only happen on the CPU that they are on, 72077ae365eSSteven Rostedt * and they only need to worry about interrupts. Reads can 72177ae365eSSteven Rostedt * happen on any CPU. 72277ae365eSSteven Rostedt * 72377ae365eSSteven Rostedt * The reader page is always off the ring buffer, but when the 72477ae365eSSteven Rostedt * reader finishes with a page, it needs to swap its page with 72577ae365eSSteven Rostedt * a new one from the buffer. The reader needs to take from 72677ae365eSSteven Rostedt * the head (writes go to the tail). But if a writer is in overwrite 72777ae365eSSteven Rostedt * mode and wraps, it must push the head page forward. 72877ae365eSSteven Rostedt * 72977ae365eSSteven Rostedt * Here lies the problem. 73077ae365eSSteven Rostedt * 73177ae365eSSteven Rostedt * The reader must be careful to replace only the head page, and 73277ae365eSSteven Rostedt * not another one. As described at the top of the file in the 73377ae365eSSteven Rostedt * ASCII art, the reader sets its old page to point to the next 73477ae365eSSteven Rostedt * page after head. It then sets the page after head to point to 73577ae365eSSteven Rostedt * the old reader page. But if the writer moves the head page 73677ae365eSSteven Rostedt * during this operation, the reader could end up with the tail. 73777ae365eSSteven Rostedt * 73877ae365eSSteven Rostedt * We use cmpxchg to help prevent this race. We also do something 73977ae365eSSteven Rostedt * special with the page before head. We set the LSB to 1. 74077ae365eSSteven Rostedt * 74177ae365eSSteven Rostedt * When the writer must push the page forward, it will clear the 74277ae365eSSteven Rostedt * bit that points to the head page, move the head, and then set 74377ae365eSSteven Rostedt * the bit that points to the new head page. 74477ae365eSSteven Rostedt * 74577ae365eSSteven Rostedt * We also don't want an interrupt coming in and moving the head 74677ae365eSSteven Rostedt * page on another writer. Thus we use the second LSB to catch 74777ae365eSSteven Rostedt * that too. Thus: 74877ae365eSSteven Rostedt * 74977ae365eSSteven Rostedt * head->list->prev->next bit 1 bit 0 75077ae365eSSteven Rostedt * ------- ------- 75177ae365eSSteven Rostedt * Normal page 0 0 75277ae365eSSteven Rostedt * Points to head page 0 1 75377ae365eSSteven Rostedt * New head page 1 0 75477ae365eSSteven Rostedt * 75577ae365eSSteven Rostedt * Note we can not trust the prev pointer of the head page, because: 75677ae365eSSteven Rostedt * 75777ae365eSSteven Rostedt * +----+ +-----+ +-----+ 75877ae365eSSteven Rostedt * | |------>| T |---X--->| N | 75977ae365eSSteven Rostedt * | |<------| | | | 76077ae365eSSteven Rostedt * +----+ +-----+ +-----+ 76177ae365eSSteven Rostedt * ^ ^ | 76277ae365eSSteven Rostedt * | +-----+ | | 76377ae365eSSteven Rostedt * +----------| R |----------+ | 76477ae365eSSteven Rostedt * | |<-----------+ 76577ae365eSSteven Rostedt * +-----+ 76677ae365eSSteven Rostedt * 76777ae365eSSteven Rostedt * Key: ---X--> HEAD flag set in pointer 76877ae365eSSteven Rostedt * T Tail page 76977ae365eSSteven Rostedt * R Reader page 77077ae365eSSteven Rostedt * N Next page 77177ae365eSSteven Rostedt * 77277ae365eSSteven Rostedt * (see __rb_reserve_next() to see where this happens) 77377ae365eSSteven Rostedt * 77477ae365eSSteven Rostedt * What the above shows is that the reader just swapped out 77577ae365eSSteven Rostedt * the reader page with a page in the buffer, but before it 77677ae365eSSteven Rostedt * could make the new header point back to the new page added 77777ae365eSSteven Rostedt * it was preempted by a writer. The writer moved forward onto 77877ae365eSSteven Rostedt * the new page added by the reader and is about to move forward 77977ae365eSSteven Rostedt * again. 78077ae365eSSteven Rostedt * 78177ae365eSSteven Rostedt * You can see, it is legitimate for the previous pointer of 78277ae365eSSteven Rostedt * the head (or any page) not to point back to itself. But only 78377ae365eSSteven Rostedt * temporarially. 78477ae365eSSteven Rostedt */ 78577ae365eSSteven Rostedt 78677ae365eSSteven Rostedt #define RB_PAGE_NORMAL 0UL 78777ae365eSSteven Rostedt #define RB_PAGE_HEAD 1UL 78877ae365eSSteven Rostedt #define RB_PAGE_UPDATE 2UL 78977ae365eSSteven Rostedt 79077ae365eSSteven Rostedt 79177ae365eSSteven Rostedt #define RB_FLAG_MASK 3UL 79277ae365eSSteven Rostedt 79377ae365eSSteven Rostedt /* PAGE_MOVED is not part of the mask */ 79477ae365eSSteven Rostedt #define RB_PAGE_MOVED 4UL 79577ae365eSSteven Rostedt 79677ae365eSSteven Rostedt /* 79777ae365eSSteven Rostedt * rb_list_head - remove any bit 79877ae365eSSteven Rostedt */ 79977ae365eSSteven Rostedt static struct list_head *rb_list_head(struct list_head *list) 80077ae365eSSteven Rostedt { 80177ae365eSSteven Rostedt unsigned long val = (unsigned long)list; 80277ae365eSSteven Rostedt 80377ae365eSSteven Rostedt return (struct list_head *)(val & ~RB_FLAG_MASK); 80477ae365eSSteven Rostedt } 80577ae365eSSteven Rostedt 80677ae365eSSteven Rostedt /* 8076d3f1e12SJiri Olsa * rb_is_head_page - test if the given page is the head page 80877ae365eSSteven Rostedt * 80977ae365eSSteven Rostedt * Because the reader may move the head_page pointer, we can 81077ae365eSSteven Rostedt * not trust what the head page is (it may be pointing to 81177ae365eSSteven Rostedt * the reader page). But if the next page is a header page, 81277ae365eSSteven Rostedt * its flags will be non zero. 81377ae365eSSteven Rostedt */ 81442b16b3fSJesper Juhl static inline int 81577ae365eSSteven Rostedt rb_is_head_page(struct ring_buffer_per_cpu *cpu_buffer, 81677ae365eSSteven Rostedt struct buffer_page *page, struct list_head *list) 81777ae365eSSteven Rostedt { 81877ae365eSSteven Rostedt unsigned long val; 81977ae365eSSteven Rostedt 82077ae365eSSteven Rostedt val = (unsigned long)list->next; 82177ae365eSSteven Rostedt 82277ae365eSSteven Rostedt if ((val & ~RB_FLAG_MASK) != (unsigned long)&page->list) 82377ae365eSSteven Rostedt return RB_PAGE_MOVED; 82477ae365eSSteven Rostedt 82577ae365eSSteven Rostedt return val & RB_FLAG_MASK; 82677ae365eSSteven Rostedt } 82777ae365eSSteven Rostedt 82877ae365eSSteven Rostedt /* 82977ae365eSSteven Rostedt * rb_is_reader_page 83077ae365eSSteven Rostedt * 83177ae365eSSteven Rostedt * The unique thing about the reader page, is that, if the 83277ae365eSSteven Rostedt * writer is ever on it, the previous pointer never points 83377ae365eSSteven Rostedt * back to the reader page. 83477ae365eSSteven Rostedt */ 83506ca3209SYaowei Bai static bool rb_is_reader_page(struct buffer_page *page) 83677ae365eSSteven Rostedt { 83777ae365eSSteven Rostedt struct list_head *list = page->list.prev; 83877ae365eSSteven Rostedt 83977ae365eSSteven Rostedt return rb_list_head(list->next) != &page->list; 84077ae365eSSteven Rostedt } 84177ae365eSSteven Rostedt 84277ae365eSSteven Rostedt /* 84377ae365eSSteven Rostedt * rb_set_list_to_head - set a list_head to be pointing to head. 84477ae365eSSteven Rostedt */ 84577ae365eSSteven Rostedt static void rb_set_list_to_head(struct ring_buffer_per_cpu *cpu_buffer, 84677ae365eSSteven Rostedt struct list_head *list) 84777ae365eSSteven Rostedt { 84877ae365eSSteven Rostedt unsigned long *ptr; 84977ae365eSSteven Rostedt 85077ae365eSSteven Rostedt ptr = (unsigned long *)&list->next; 85177ae365eSSteven Rostedt *ptr |= RB_PAGE_HEAD; 85277ae365eSSteven Rostedt *ptr &= ~RB_PAGE_UPDATE; 85377ae365eSSteven Rostedt } 85477ae365eSSteven Rostedt 85577ae365eSSteven Rostedt /* 85677ae365eSSteven Rostedt * rb_head_page_activate - sets up head page 85777ae365eSSteven Rostedt */ 85877ae365eSSteven Rostedt static void rb_head_page_activate(struct ring_buffer_per_cpu *cpu_buffer) 85977ae365eSSteven Rostedt { 86077ae365eSSteven Rostedt struct buffer_page *head; 86177ae365eSSteven Rostedt 86277ae365eSSteven Rostedt head = cpu_buffer->head_page; 86377ae365eSSteven Rostedt if (!head) 86477ae365eSSteven Rostedt return; 86577ae365eSSteven Rostedt 86677ae365eSSteven Rostedt /* 86777ae365eSSteven Rostedt * Set the previous list pointer to have the HEAD flag. 86877ae365eSSteven Rostedt */ 86977ae365eSSteven Rostedt rb_set_list_to_head(cpu_buffer, head->list.prev); 87077ae365eSSteven Rostedt } 87177ae365eSSteven Rostedt 87277ae365eSSteven Rostedt static void rb_list_head_clear(struct list_head *list) 87377ae365eSSteven Rostedt { 87477ae365eSSteven Rostedt unsigned long *ptr = (unsigned long *)&list->next; 87577ae365eSSteven Rostedt 87677ae365eSSteven Rostedt *ptr &= ~RB_FLAG_MASK; 87777ae365eSSteven Rostedt } 87877ae365eSSteven Rostedt 87977ae365eSSteven Rostedt /* 88077ae365eSSteven Rostedt * rb_head_page_dactivate - clears head page ptr (for free list) 88177ae365eSSteven Rostedt */ 88277ae365eSSteven Rostedt static void 88377ae365eSSteven Rostedt rb_head_page_deactivate(struct ring_buffer_per_cpu *cpu_buffer) 88477ae365eSSteven Rostedt { 88577ae365eSSteven Rostedt struct list_head *hd; 88677ae365eSSteven Rostedt 88777ae365eSSteven Rostedt /* Go through the whole list and clear any pointers found. */ 88877ae365eSSteven Rostedt rb_list_head_clear(cpu_buffer->pages); 88977ae365eSSteven Rostedt 89077ae365eSSteven Rostedt list_for_each(hd, cpu_buffer->pages) 89177ae365eSSteven Rostedt rb_list_head_clear(hd); 89277ae365eSSteven Rostedt } 89377ae365eSSteven Rostedt 89477ae365eSSteven Rostedt static int rb_head_page_set(struct ring_buffer_per_cpu *cpu_buffer, 89577ae365eSSteven Rostedt struct buffer_page *head, 89677ae365eSSteven Rostedt struct buffer_page *prev, 89777ae365eSSteven Rostedt int old_flag, int new_flag) 89877ae365eSSteven Rostedt { 89977ae365eSSteven Rostedt struct list_head *list; 90077ae365eSSteven Rostedt unsigned long val = (unsigned long)&head->list; 90177ae365eSSteven Rostedt unsigned long ret; 90277ae365eSSteven Rostedt 90377ae365eSSteven Rostedt list = &prev->list; 90477ae365eSSteven Rostedt 90577ae365eSSteven Rostedt val &= ~RB_FLAG_MASK; 90677ae365eSSteven Rostedt 90708a40816SSteven Rostedt ret = cmpxchg((unsigned long *)&list->next, 90877ae365eSSteven Rostedt val | old_flag, val | new_flag); 90977ae365eSSteven Rostedt 91077ae365eSSteven Rostedt /* check if the reader took the page */ 91177ae365eSSteven Rostedt if ((ret & ~RB_FLAG_MASK) != val) 91277ae365eSSteven Rostedt return RB_PAGE_MOVED; 91377ae365eSSteven Rostedt 91477ae365eSSteven Rostedt return ret & RB_FLAG_MASK; 91577ae365eSSteven Rostedt } 91677ae365eSSteven Rostedt 91777ae365eSSteven Rostedt static int rb_head_page_set_update(struct ring_buffer_per_cpu *cpu_buffer, 91877ae365eSSteven Rostedt struct buffer_page *head, 91977ae365eSSteven Rostedt struct buffer_page *prev, 92077ae365eSSteven Rostedt int old_flag) 92177ae365eSSteven Rostedt { 92277ae365eSSteven Rostedt return rb_head_page_set(cpu_buffer, head, prev, 92377ae365eSSteven Rostedt old_flag, RB_PAGE_UPDATE); 92477ae365eSSteven Rostedt } 92577ae365eSSteven Rostedt 92677ae365eSSteven Rostedt static int rb_head_page_set_head(struct ring_buffer_per_cpu *cpu_buffer, 92777ae365eSSteven Rostedt struct buffer_page *head, 92877ae365eSSteven Rostedt struct buffer_page *prev, 92977ae365eSSteven Rostedt int old_flag) 93077ae365eSSteven Rostedt { 93177ae365eSSteven Rostedt return rb_head_page_set(cpu_buffer, head, prev, 93277ae365eSSteven Rostedt old_flag, RB_PAGE_HEAD); 93377ae365eSSteven Rostedt } 93477ae365eSSteven Rostedt 93577ae365eSSteven Rostedt static int rb_head_page_set_normal(struct ring_buffer_per_cpu *cpu_buffer, 93677ae365eSSteven Rostedt struct buffer_page *head, 93777ae365eSSteven Rostedt struct buffer_page *prev, 93877ae365eSSteven Rostedt int old_flag) 93977ae365eSSteven Rostedt { 94077ae365eSSteven Rostedt return rb_head_page_set(cpu_buffer, head, prev, 94177ae365eSSteven Rostedt old_flag, RB_PAGE_NORMAL); 94277ae365eSSteven Rostedt } 94377ae365eSSteven Rostedt 94477ae365eSSteven Rostedt static inline void rb_inc_page(struct ring_buffer_per_cpu *cpu_buffer, 94577ae365eSSteven Rostedt struct buffer_page **bpage) 94677ae365eSSteven Rostedt { 94777ae365eSSteven Rostedt struct list_head *p = rb_list_head((*bpage)->list.next); 94877ae365eSSteven Rostedt 94977ae365eSSteven Rostedt *bpage = list_entry(p, struct buffer_page, list); 95077ae365eSSteven Rostedt } 95177ae365eSSteven Rostedt 95277ae365eSSteven Rostedt static struct buffer_page * 95377ae365eSSteven Rostedt rb_set_head_page(struct ring_buffer_per_cpu *cpu_buffer) 95477ae365eSSteven Rostedt { 95577ae365eSSteven Rostedt struct buffer_page *head; 95677ae365eSSteven Rostedt struct buffer_page *page; 95777ae365eSSteven Rostedt struct list_head *list; 95877ae365eSSteven Rostedt int i; 95977ae365eSSteven Rostedt 96077ae365eSSteven Rostedt if (RB_WARN_ON(cpu_buffer, !cpu_buffer->head_page)) 96177ae365eSSteven Rostedt return NULL; 96277ae365eSSteven Rostedt 96377ae365eSSteven Rostedt /* sanity check */ 96477ae365eSSteven Rostedt list = cpu_buffer->pages; 96577ae365eSSteven Rostedt if (RB_WARN_ON(cpu_buffer, rb_list_head(list->prev->next) != list)) 96677ae365eSSteven Rostedt return NULL; 96777ae365eSSteven Rostedt 96877ae365eSSteven Rostedt page = head = cpu_buffer->head_page; 96977ae365eSSteven Rostedt /* 97077ae365eSSteven Rostedt * It is possible that the writer moves the header behind 97177ae365eSSteven Rostedt * where we started, and we miss in one loop. 97277ae365eSSteven Rostedt * A second loop should grab the header, but we'll do 97377ae365eSSteven Rostedt * three loops just because I'm paranoid. 97477ae365eSSteven Rostedt */ 97577ae365eSSteven Rostedt for (i = 0; i < 3; i++) { 97677ae365eSSteven Rostedt do { 97777ae365eSSteven Rostedt if (rb_is_head_page(cpu_buffer, page, page->list.prev)) { 97877ae365eSSteven Rostedt cpu_buffer->head_page = page; 97977ae365eSSteven Rostedt return page; 98077ae365eSSteven Rostedt } 98177ae365eSSteven Rostedt rb_inc_page(cpu_buffer, &page); 98277ae365eSSteven Rostedt } while (page != head); 98377ae365eSSteven Rostedt } 98477ae365eSSteven Rostedt 98577ae365eSSteven Rostedt RB_WARN_ON(cpu_buffer, 1); 98677ae365eSSteven Rostedt 98777ae365eSSteven Rostedt return NULL; 98877ae365eSSteven Rostedt } 98977ae365eSSteven Rostedt 99077ae365eSSteven Rostedt static int rb_head_page_replace(struct buffer_page *old, 99177ae365eSSteven Rostedt struct buffer_page *new) 99277ae365eSSteven Rostedt { 99377ae365eSSteven Rostedt unsigned long *ptr = (unsigned long *)&old->list.prev->next; 99477ae365eSSteven Rostedt unsigned long val; 99577ae365eSSteven Rostedt unsigned long ret; 99677ae365eSSteven Rostedt 99777ae365eSSteven Rostedt val = *ptr & ~RB_FLAG_MASK; 99877ae365eSSteven Rostedt val |= RB_PAGE_HEAD; 99977ae365eSSteven Rostedt 100008a40816SSteven Rostedt ret = cmpxchg(ptr, val, (unsigned long)&new->list); 100177ae365eSSteven Rostedt 100277ae365eSSteven Rostedt return ret == val; 100377ae365eSSteven Rostedt } 100477ae365eSSteven Rostedt 100577ae365eSSteven Rostedt /* 100677ae365eSSteven Rostedt * rb_tail_page_update - move the tail page forward 100777ae365eSSteven Rostedt */ 100870004986SSteven Rostedt (Red Hat) static void rb_tail_page_update(struct ring_buffer_per_cpu *cpu_buffer, 100977ae365eSSteven Rostedt struct buffer_page *tail_page, 101077ae365eSSteven Rostedt struct buffer_page *next_page) 101177ae365eSSteven Rostedt { 101277ae365eSSteven Rostedt unsigned long old_entries; 101377ae365eSSteven Rostedt unsigned long old_write; 101477ae365eSSteven Rostedt 101577ae365eSSteven Rostedt /* 101677ae365eSSteven Rostedt * The tail page now needs to be moved forward. 101777ae365eSSteven Rostedt * 101877ae365eSSteven Rostedt * We need to reset the tail page, but without messing 101977ae365eSSteven Rostedt * with possible erasing of data brought in by interrupts 102077ae365eSSteven Rostedt * that have moved the tail page and are currently on it. 102177ae365eSSteven Rostedt * 102277ae365eSSteven Rostedt * We add a counter to the write field to denote this. 102377ae365eSSteven Rostedt */ 102477ae365eSSteven Rostedt old_write = local_add_return(RB_WRITE_INTCNT, &next_page->write); 102577ae365eSSteven Rostedt old_entries = local_add_return(RB_WRITE_INTCNT, &next_page->entries); 102677ae365eSSteven Rostedt 102777ae365eSSteven Rostedt /* 102877ae365eSSteven Rostedt * Just make sure we have seen our old_write and synchronize 102977ae365eSSteven Rostedt * with any interrupts that come in. 103077ae365eSSteven Rostedt */ 103177ae365eSSteven Rostedt barrier(); 103277ae365eSSteven Rostedt 103377ae365eSSteven Rostedt /* 103477ae365eSSteven Rostedt * If the tail page is still the same as what we think 103577ae365eSSteven Rostedt * it is, then it is up to us to update the tail 103677ae365eSSteven Rostedt * pointer. 103777ae365eSSteven Rostedt */ 10388573636eSSteven Rostedt (Red Hat) if (tail_page == READ_ONCE(cpu_buffer->tail_page)) { 103977ae365eSSteven Rostedt /* Zero the write counter */ 104077ae365eSSteven Rostedt unsigned long val = old_write & ~RB_WRITE_MASK; 104177ae365eSSteven Rostedt unsigned long eval = old_entries & ~RB_WRITE_MASK; 104277ae365eSSteven Rostedt 104377ae365eSSteven Rostedt /* 104477ae365eSSteven Rostedt * This will only succeed if an interrupt did 104577ae365eSSteven Rostedt * not come in and change it. In which case, we 104677ae365eSSteven Rostedt * do not want to modify it. 1047da706d8bSLai Jiangshan * 1048da706d8bSLai Jiangshan * We add (void) to let the compiler know that we do not care 1049da706d8bSLai Jiangshan * about the return value of these functions. We use the 1050da706d8bSLai Jiangshan * cmpxchg to only update if an interrupt did not already 1051da706d8bSLai Jiangshan * do it for us. If the cmpxchg fails, we don't care. 105277ae365eSSteven Rostedt */ 1053da706d8bSLai Jiangshan (void)local_cmpxchg(&next_page->write, old_write, val); 1054da706d8bSLai Jiangshan (void)local_cmpxchg(&next_page->entries, old_entries, eval); 105577ae365eSSteven Rostedt 105677ae365eSSteven Rostedt /* 105777ae365eSSteven Rostedt * No need to worry about races with clearing out the commit. 105877ae365eSSteven Rostedt * it only can increment when a commit takes place. But that 105977ae365eSSteven Rostedt * only happens in the outer most nested commit. 106077ae365eSSteven Rostedt */ 106177ae365eSSteven Rostedt local_set(&next_page->page->commit, 0); 106277ae365eSSteven Rostedt 106370004986SSteven Rostedt (Red Hat) /* Again, either we update tail_page or an interrupt does */ 106470004986SSteven Rostedt (Red Hat) (void)cmpxchg(&cpu_buffer->tail_page, tail_page, next_page); 106577ae365eSSteven Rostedt } 106677ae365eSSteven Rostedt } 106777ae365eSSteven Rostedt 106877ae365eSSteven Rostedt static int rb_check_bpage(struct ring_buffer_per_cpu *cpu_buffer, 106977ae365eSSteven Rostedt struct buffer_page *bpage) 107077ae365eSSteven Rostedt { 107177ae365eSSteven Rostedt unsigned long val = (unsigned long)bpage; 107277ae365eSSteven Rostedt 107377ae365eSSteven Rostedt if (RB_WARN_ON(cpu_buffer, val & RB_FLAG_MASK)) 107477ae365eSSteven Rostedt return 1; 107577ae365eSSteven Rostedt 107677ae365eSSteven Rostedt return 0; 107777ae365eSSteven Rostedt } 107877ae365eSSteven Rostedt 107977ae365eSSteven Rostedt /** 108077ae365eSSteven Rostedt * rb_check_list - make sure a pointer to a list has the last bits zero 108177ae365eSSteven Rostedt */ 108277ae365eSSteven Rostedt static int rb_check_list(struct ring_buffer_per_cpu *cpu_buffer, 108377ae365eSSteven Rostedt struct list_head *list) 108477ae365eSSteven Rostedt { 108577ae365eSSteven Rostedt if (RB_WARN_ON(cpu_buffer, rb_list_head(list->prev) != list->prev)) 108677ae365eSSteven Rostedt return 1; 108777ae365eSSteven Rostedt if (RB_WARN_ON(cpu_buffer, rb_list_head(list->next) != list->next)) 108877ae365eSSteven Rostedt return 1; 108977ae365eSSteven Rostedt return 0; 109077ae365eSSteven Rostedt } 109177ae365eSSteven Rostedt 10927a8e76a3SSteven Rostedt /** 1093d611851bSzhangwei(Jovi) * rb_check_pages - integrity check of buffer pages 10947a8e76a3SSteven Rostedt * @cpu_buffer: CPU buffer with pages to test 10957a8e76a3SSteven Rostedt * 1096c3706f00SWenji Huang * As a safety measure we check to make sure the data pages have not 10977a8e76a3SSteven Rostedt * been corrupted. 10987a8e76a3SSteven Rostedt */ 10997a8e76a3SSteven Rostedt static int rb_check_pages(struct ring_buffer_per_cpu *cpu_buffer) 11007a8e76a3SSteven Rostedt { 11013adc54faSSteven Rostedt struct list_head *head = cpu_buffer->pages; 1102044fa782SSteven Rostedt struct buffer_page *bpage, *tmp; 11037a8e76a3SSteven Rostedt 1104308f7eebSSteven Rostedt /* Reset the head page if it exists */ 1105308f7eebSSteven Rostedt if (cpu_buffer->head_page) 1106308f7eebSSteven Rostedt rb_set_head_page(cpu_buffer); 1107308f7eebSSteven Rostedt 110877ae365eSSteven Rostedt rb_head_page_deactivate(cpu_buffer); 110977ae365eSSteven Rostedt 11103e89c7bbSSteven Rostedt if (RB_WARN_ON(cpu_buffer, head->next->prev != head)) 11113e89c7bbSSteven Rostedt return -1; 11123e89c7bbSSteven Rostedt if (RB_WARN_ON(cpu_buffer, head->prev->next != head)) 11133e89c7bbSSteven Rostedt return -1; 11147a8e76a3SSteven Rostedt 111577ae365eSSteven Rostedt if (rb_check_list(cpu_buffer, head)) 111677ae365eSSteven Rostedt return -1; 111777ae365eSSteven Rostedt 1118044fa782SSteven Rostedt list_for_each_entry_safe(bpage, tmp, head, list) { 11193e89c7bbSSteven Rostedt if (RB_WARN_ON(cpu_buffer, 1120044fa782SSteven Rostedt bpage->list.next->prev != &bpage->list)) 11213e89c7bbSSteven Rostedt return -1; 11223e89c7bbSSteven Rostedt if (RB_WARN_ON(cpu_buffer, 1123044fa782SSteven Rostedt bpage->list.prev->next != &bpage->list)) 11243e89c7bbSSteven Rostedt return -1; 112577ae365eSSteven Rostedt if (rb_check_list(cpu_buffer, &bpage->list)) 112677ae365eSSteven Rostedt return -1; 11277a8e76a3SSteven Rostedt } 11287a8e76a3SSteven Rostedt 112977ae365eSSteven Rostedt rb_head_page_activate(cpu_buffer); 113077ae365eSSteven Rostedt 11317a8e76a3SSteven Rostedt return 0; 11327a8e76a3SSteven Rostedt } 11337a8e76a3SSteven Rostedt 11349b94a8fbSSteven Rostedt (Red Hat) static int __rb_allocate_pages(long nr_pages, struct list_head *pages, int cpu) 11357a8e76a3SSteven Rostedt { 1136044fa782SSteven Rostedt struct buffer_page *bpage, *tmp; 11379b94a8fbSSteven Rostedt (Red Hat) long i; 11383adc54faSSteven Rostedt 11397a8e76a3SSteven Rostedt for (i = 0; i < nr_pages; i++) { 11407ea59064SVaibhav Nagarnaik struct page *page; 1141d7ec4bfeSVaibhav Nagarnaik /* 114284861885SJoel Fernandes * __GFP_RETRY_MAYFAIL flag makes sure that the allocation fails 114384861885SJoel Fernandes * gracefully without invoking oom-killer and the system is not 114484861885SJoel Fernandes * destabilized. 1145d7ec4bfeSVaibhav Nagarnaik */ 1146044fa782SSteven Rostedt bpage = kzalloc_node(ALIGN(sizeof(*bpage), cache_line_size()), 114784861885SJoel Fernandes GFP_KERNEL | __GFP_RETRY_MAYFAIL, 1148438ced17SVaibhav Nagarnaik cpu_to_node(cpu)); 1149044fa782SSteven Rostedt if (!bpage) 1150e4c2ce82SSteven Rostedt goto free_pages; 115177ae365eSSteven Rostedt 1152438ced17SVaibhav Nagarnaik list_add(&bpage->list, pages); 115377ae365eSSteven Rostedt 1154438ced17SVaibhav Nagarnaik page = alloc_pages_node(cpu_to_node(cpu), 115584861885SJoel Fernandes GFP_KERNEL | __GFP_RETRY_MAYFAIL, 0); 11567ea59064SVaibhav Nagarnaik if (!page) 11577a8e76a3SSteven Rostedt goto free_pages; 11587ea59064SVaibhav Nagarnaik bpage->page = page_address(page); 1159044fa782SSteven Rostedt rb_init_page(bpage->page); 11607a8e76a3SSteven Rostedt } 11617a8e76a3SSteven Rostedt 1162438ced17SVaibhav Nagarnaik return 0; 1163438ced17SVaibhav Nagarnaik 1164438ced17SVaibhav Nagarnaik free_pages: 1165438ced17SVaibhav Nagarnaik list_for_each_entry_safe(bpage, tmp, pages, list) { 1166438ced17SVaibhav Nagarnaik list_del_init(&bpage->list); 1167438ced17SVaibhav Nagarnaik free_buffer_page(bpage); 1168438ced17SVaibhav Nagarnaik } 1169438ced17SVaibhav Nagarnaik 1170438ced17SVaibhav Nagarnaik return -ENOMEM; 1171438ced17SVaibhav Nagarnaik } 1172438ced17SVaibhav Nagarnaik 1173438ced17SVaibhav Nagarnaik static int rb_allocate_pages(struct ring_buffer_per_cpu *cpu_buffer, 11749b94a8fbSSteven Rostedt (Red Hat) unsigned long nr_pages) 1175438ced17SVaibhav Nagarnaik { 1176438ced17SVaibhav Nagarnaik LIST_HEAD(pages); 1177438ced17SVaibhav Nagarnaik 1178438ced17SVaibhav Nagarnaik WARN_ON(!nr_pages); 1179438ced17SVaibhav Nagarnaik 1180438ced17SVaibhav Nagarnaik if (__rb_allocate_pages(nr_pages, &pages, cpu_buffer->cpu)) 1181438ced17SVaibhav Nagarnaik return -ENOMEM; 1182438ced17SVaibhav Nagarnaik 11833adc54faSSteven Rostedt /* 11843adc54faSSteven Rostedt * The ring buffer page list is a circular list that does not 11853adc54faSSteven Rostedt * start and end with a list head. All page list items point to 11863adc54faSSteven Rostedt * other pages. 11873adc54faSSteven Rostedt */ 11883adc54faSSteven Rostedt cpu_buffer->pages = pages.next; 11893adc54faSSteven Rostedt list_del(&pages); 11907a8e76a3SSteven Rostedt 1191438ced17SVaibhav Nagarnaik cpu_buffer->nr_pages = nr_pages; 1192438ced17SVaibhav Nagarnaik 11937a8e76a3SSteven Rostedt rb_check_pages(cpu_buffer); 11947a8e76a3SSteven Rostedt 11957a8e76a3SSteven Rostedt return 0; 11967a8e76a3SSteven Rostedt } 11977a8e76a3SSteven Rostedt 11987a8e76a3SSteven Rostedt static struct ring_buffer_per_cpu * 11999b94a8fbSSteven Rostedt (Red Hat) rb_allocate_cpu_buffer(struct ring_buffer *buffer, long nr_pages, int cpu) 12007a8e76a3SSteven Rostedt { 12017a8e76a3SSteven Rostedt struct ring_buffer_per_cpu *cpu_buffer; 1202044fa782SSteven Rostedt struct buffer_page *bpage; 12037ea59064SVaibhav Nagarnaik struct page *page; 12047a8e76a3SSteven Rostedt int ret; 12057a8e76a3SSteven Rostedt 12067a8e76a3SSteven Rostedt cpu_buffer = kzalloc_node(ALIGN(sizeof(*cpu_buffer), cache_line_size()), 12077a8e76a3SSteven Rostedt GFP_KERNEL, cpu_to_node(cpu)); 12087a8e76a3SSteven Rostedt if (!cpu_buffer) 12097a8e76a3SSteven Rostedt return NULL; 12107a8e76a3SSteven Rostedt 12117a8e76a3SSteven Rostedt cpu_buffer->cpu = cpu; 12127a8e76a3SSteven Rostedt cpu_buffer->buffer = buffer; 12135389f6faSThomas Gleixner raw_spin_lock_init(&cpu_buffer->reader_lock); 12141f8a6a10SPeter Zijlstra lockdep_set_class(&cpu_buffer->reader_lock, buffer->reader_lock_key); 1215edc35bd7SThomas Gleixner cpu_buffer->lock = (arch_spinlock_t)__ARCH_SPIN_LOCK_UNLOCKED; 121683f40318SVaibhav Nagarnaik INIT_WORK(&cpu_buffer->update_pages_work, update_pages_handler); 121705fdd70dSVaibhav Nagarnaik init_completion(&cpu_buffer->update_done); 121815693458SSteven Rostedt (Red Hat) init_irq_work(&cpu_buffer->irq_work.work, rb_wake_up_waiters); 1219f1dc6725SSteven Rostedt (Red Hat) init_waitqueue_head(&cpu_buffer->irq_work.waiters); 12201e0d6714SSteven Rostedt (Red Hat) init_waitqueue_head(&cpu_buffer->irq_work.full_waiters); 12217a8e76a3SSteven Rostedt 1222044fa782SSteven Rostedt bpage = kzalloc_node(ALIGN(sizeof(*bpage), cache_line_size()), 1223e4c2ce82SSteven Rostedt GFP_KERNEL, cpu_to_node(cpu)); 1224044fa782SSteven Rostedt if (!bpage) 1225e4c2ce82SSteven Rostedt goto fail_free_buffer; 1226e4c2ce82SSteven Rostedt 122777ae365eSSteven Rostedt rb_check_bpage(cpu_buffer, bpage); 122877ae365eSSteven Rostedt 1229044fa782SSteven Rostedt cpu_buffer->reader_page = bpage; 12307ea59064SVaibhav Nagarnaik page = alloc_pages_node(cpu_to_node(cpu), GFP_KERNEL, 0); 12317ea59064SVaibhav Nagarnaik if (!page) 1232e4c2ce82SSteven Rostedt goto fail_free_reader; 12337ea59064SVaibhav Nagarnaik bpage->page = page_address(page); 1234044fa782SSteven Rostedt rb_init_page(bpage->page); 1235e4c2ce82SSteven Rostedt 1236d769041fSSteven Rostedt INIT_LIST_HEAD(&cpu_buffer->reader_page->list); 123744b99462SVaibhav Nagarnaik INIT_LIST_HEAD(&cpu_buffer->new_pages); 1238d769041fSSteven Rostedt 1239438ced17SVaibhav Nagarnaik ret = rb_allocate_pages(cpu_buffer, nr_pages); 12407a8e76a3SSteven Rostedt if (ret < 0) 1241d769041fSSteven Rostedt goto fail_free_reader; 12427a8e76a3SSteven Rostedt 12437a8e76a3SSteven Rostedt cpu_buffer->head_page 12443adc54faSSteven Rostedt = list_entry(cpu_buffer->pages, struct buffer_page, list); 1245bf41a158SSteven Rostedt cpu_buffer->tail_page = cpu_buffer->commit_page = cpu_buffer->head_page; 12467a8e76a3SSteven Rostedt 124777ae365eSSteven Rostedt rb_head_page_activate(cpu_buffer); 124877ae365eSSteven Rostedt 12497a8e76a3SSteven Rostedt return cpu_buffer; 12507a8e76a3SSteven Rostedt 1251d769041fSSteven Rostedt fail_free_reader: 1252d769041fSSteven Rostedt free_buffer_page(cpu_buffer->reader_page); 1253d769041fSSteven Rostedt 12547a8e76a3SSteven Rostedt fail_free_buffer: 12557a8e76a3SSteven Rostedt kfree(cpu_buffer); 12567a8e76a3SSteven Rostedt return NULL; 12577a8e76a3SSteven Rostedt } 12587a8e76a3SSteven Rostedt 12597a8e76a3SSteven Rostedt static void rb_free_cpu_buffer(struct ring_buffer_per_cpu *cpu_buffer) 12607a8e76a3SSteven Rostedt { 12613adc54faSSteven Rostedt struct list_head *head = cpu_buffer->pages; 1262044fa782SSteven Rostedt struct buffer_page *bpage, *tmp; 12637a8e76a3SSteven Rostedt 1264d769041fSSteven Rostedt free_buffer_page(cpu_buffer->reader_page); 1265d769041fSSteven Rostedt 126677ae365eSSteven Rostedt rb_head_page_deactivate(cpu_buffer); 126777ae365eSSteven Rostedt 12683adc54faSSteven Rostedt if (head) { 1269044fa782SSteven Rostedt list_for_each_entry_safe(bpage, tmp, head, list) { 1270044fa782SSteven Rostedt list_del_init(&bpage->list); 1271044fa782SSteven Rostedt free_buffer_page(bpage); 12727a8e76a3SSteven Rostedt } 12733adc54faSSteven Rostedt bpage = list_entry(head, struct buffer_page, list); 12743adc54faSSteven Rostedt free_buffer_page(bpage); 12753adc54faSSteven Rostedt } 12763adc54faSSteven Rostedt 12777a8e76a3SSteven Rostedt kfree(cpu_buffer); 12787a8e76a3SSteven Rostedt } 12797a8e76a3SSteven Rostedt 12807a8e76a3SSteven Rostedt /** 1281d611851bSzhangwei(Jovi) * __ring_buffer_alloc - allocate a new ring_buffer 128268814b58SRobert Richter * @size: the size in bytes per cpu that is needed. 12837a8e76a3SSteven Rostedt * @flags: attributes to set for the ring buffer. 12847a8e76a3SSteven Rostedt * 12857a8e76a3SSteven Rostedt * Currently the only flag that is available is the RB_FL_OVERWRITE 12867a8e76a3SSteven Rostedt * flag. This flag means that the buffer will overwrite old data 12877a8e76a3SSteven Rostedt * when the buffer wraps. If this flag is not set, the buffer will 12887a8e76a3SSteven Rostedt * drop data when the tail hits the head. 12897a8e76a3SSteven Rostedt */ 12901f8a6a10SPeter Zijlstra struct ring_buffer *__ring_buffer_alloc(unsigned long size, unsigned flags, 12911f8a6a10SPeter Zijlstra struct lock_class_key *key) 12927a8e76a3SSteven Rostedt { 12937a8e76a3SSteven Rostedt struct ring_buffer *buffer; 12949b94a8fbSSteven Rostedt (Red Hat) long nr_pages; 12957a8e76a3SSteven Rostedt int bsize; 12969b94a8fbSSteven Rostedt (Red Hat) int cpu; 1297b32614c0SSebastian Andrzej Siewior int ret; 12987a8e76a3SSteven Rostedt 12997a8e76a3SSteven Rostedt /* keep it in its own cache line */ 13007a8e76a3SSteven Rostedt buffer = kzalloc(ALIGN(sizeof(*buffer), cache_line_size()), 13017a8e76a3SSteven Rostedt GFP_KERNEL); 13027a8e76a3SSteven Rostedt if (!buffer) 13037a8e76a3SSteven Rostedt return NULL; 13047a8e76a3SSteven Rostedt 1305b18cc3deSSebastian Andrzej Siewior if (!zalloc_cpumask_var(&buffer->cpumask, GFP_KERNEL)) 13069e01c1b7SRusty Russell goto fail_free_buffer; 13079e01c1b7SRusty Russell 1308438ced17SVaibhav Nagarnaik nr_pages = DIV_ROUND_UP(size, BUF_PAGE_SIZE); 13097a8e76a3SSteven Rostedt buffer->flags = flags; 131037886f6aSSteven Rostedt buffer->clock = trace_clock_local; 13111f8a6a10SPeter Zijlstra buffer->reader_lock_key = key; 13127a8e76a3SSteven Rostedt 131315693458SSteven Rostedt (Red Hat) init_irq_work(&buffer->irq_work.work, rb_wake_up_waiters); 1314f1dc6725SSteven Rostedt (Red Hat) init_waitqueue_head(&buffer->irq_work.waiters); 131515693458SSteven Rostedt (Red Hat) 13167a8e76a3SSteven Rostedt /* need at least two pages */ 1317438ced17SVaibhav Nagarnaik if (nr_pages < 2) 1318438ced17SVaibhav Nagarnaik nr_pages = 2; 13197a8e76a3SSteven Rostedt 13207a8e76a3SSteven Rostedt buffer->cpus = nr_cpu_ids; 13217a8e76a3SSteven Rostedt 13227a8e76a3SSteven Rostedt bsize = sizeof(void *) * nr_cpu_ids; 13237a8e76a3SSteven Rostedt buffer->buffers = kzalloc(ALIGN(bsize, cache_line_size()), 13247a8e76a3SSteven Rostedt GFP_KERNEL); 13257a8e76a3SSteven Rostedt if (!buffer->buffers) 13269e01c1b7SRusty Russell goto fail_free_cpumask; 13277a8e76a3SSteven Rostedt 1328b32614c0SSebastian Andrzej Siewior cpu = raw_smp_processor_id(); 1329b32614c0SSebastian Andrzej Siewior cpumask_set_cpu(cpu, buffer->cpumask); 1330b32614c0SSebastian Andrzej Siewior buffer->buffers[cpu] = rb_allocate_cpu_buffer(buffer, nr_pages, cpu); 13317a8e76a3SSteven Rostedt if (!buffer->buffers[cpu]) 13327a8e76a3SSteven Rostedt goto fail_free_buffers; 13337a8e76a3SSteven Rostedt 1334b32614c0SSebastian Andrzej Siewior ret = cpuhp_state_add_instance(CPUHP_TRACE_RB_PREPARE, &buffer->node); 1335b32614c0SSebastian Andrzej Siewior if (ret < 0) 1336b32614c0SSebastian Andrzej Siewior goto fail_free_buffers; 1337554f786eSSteven Rostedt 13387a8e76a3SSteven Rostedt mutex_init(&buffer->mutex); 13397a8e76a3SSteven Rostedt 13407a8e76a3SSteven Rostedt return buffer; 13417a8e76a3SSteven Rostedt 13427a8e76a3SSteven Rostedt fail_free_buffers: 13437a8e76a3SSteven Rostedt for_each_buffer_cpu(buffer, cpu) { 13447a8e76a3SSteven Rostedt if (buffer->buffers[cpu]) 13457a8e76a3SSteven Rostedt rb_free_cpu_buffer(buffer->buffers[cpu]); 13467a8e76a3SSteven Rostedt } 13477a8e76a3SSteven Rostedt kfree(buffer->buffers); 13487a8e76a3SSteven Rostedt 13499e01c1b7SRusty Russell fail_free_cpumask: 13509e01c1b7SRusty Russell free_cpumask_var(buffer->cpumask); 13519e01c1b7SRusty Russell 13527a8e76a3SSteven Rostedt fail_free_buffer: 13537a8e76a3SSteven Rostedt kfree(buffer); 13547a8e76a3SSteven Rostedt return NULL; 13557a8e76a3SSteven Rostedt } 13561f8a6a10SPeter Zijlstra EXPORT_SYMBOL_GPL(__ring_buffer_alloc); 13577a8e76a3SSteven Rostedt 13587a8e76a3SSteven Rostedt /** 13597a8e76a3SSteven Rostedt * ring_buffer_free - free a ring buffer. 13607a8e76a3SSteven Rostedt * @buffer: the buffer to free. 13617a8e76a3SSteven Rostedt */ 13627a8e76a3SSteven Rostedt void 13637a8e76a3SSteven Rostedt ring_buffer_free(struct ring_buffer *buffer) 13647a8e76a3SSteven Rostedt { 13657a8e76a3SSteven Rostedt int cpu; 13667a8e76a3SSteven Rostedt 1367b32614c0SSebastian Andrzej Siewior cpuhp_state_remove_instance(CPUHP_TRACE_RB_PREPARE, &buffer->node); 1368554f786eSSteven Rostedt 13697a8e76a3SSteven Rostedt for_each_buffer_cpu(buffer, cpu) 13707a8e76a3SSteven Rostedt rb_free_cpu_buffer(buffer->buffers[cpu]); 13717a8e76a3SSteven Rostedt 1372bd3f0221SEric Dumazet kfree(buffer->buffers); 13739e01c1b7SRusty Russell free_cpumask_var(buffer->cpumask); 13749e01c1b7SRusty Russell 13757a8e76a3SSteven Rostedt kfree(buffer); 13767a8e76a3SSteven Rostedt } 1377c4f50183SRobert Richter EXPORT_SYMBOL_GPL(ring_buffer_free); 13787a8e76a3SSteven Rostedt 137937886f6aSSteven Rostedt void ring_buffer_set_clock(struct ring_buffer *buffer, 138037886f6aSSteven Rostedt u64 (*clock)(void)) 138137886f6aSSteven Rostedt { 138237886f6aSSteven Rostedt buffer->clock = clock; 138337886f6aSSteven Rostedt } 138437886f6aSSteven Rostedt 13857a8e76a3SSteven Rostedt static void rb_reset_cpu(struct ring_buffer_per_cpu *cpu_buffer); 13867a8e76a3SSteven Rostedt 138783f40318SVaibhav Nagarnaik static inline unsigned long rb_page_entries(struct buffer_page *bpage) 13887a8e76a3SSteven Rostedt { 138983f40318SVaibhav Nagarnaik return local_read(&bpage->entries) & RB_WRITE_MASK; 139083f40318SVaibhav Nagarnaik } 139183f40318SVaibhav Nagarnaik 139283f40318SVaibhav Nagarnaik static inline unsigned long rb_page_write(struct buffer_page *bpage) 139383f40318SVaibhav Nagarnaik { 139483f40318SVaibhav Nagarnaik return local_read(&bpage->write) & RB_WRITE_MASK; 139583f40318SVaibhav Nagarnaik } 139683f40318SVaibhav Nagarnaik 13975040b4b7SVaibhav Nagarnaik static int 13989b94a8fbSSteven Rostedt (Red Hat) rb_remove_pages(struct ring_buffer_per_cpu *cpu_buffer, unsigned long nr_pages) 139983f40318SVaibhav Nagarnaik { 140083f40318SVaibhav Nagarnaik struct list_head *tail_page, *to_remove, *next_page; 140183f40318SVaibhav Nagarnaik struct buffer_page *to_remove_page, *tmp_iter_page; 140283f40318SVaibhav Nagarnaik struct buffer_page *last_page, *first_page; 14039b94a8fbSSteven Rostedt (Red Hat) unsigned long nr_removed; 140483f40318SVaibhav Nagarnaik unsigned long head_bit; 140583f40318SVaibhav Nagarnaik int page_entries; 140683f40318SVaibhav Nagarnaik 140783f40318SVaibhav Nagarnaik head_bit = 0; 14087a8e76a3SSteven Rostedt 14095389f6faSThomas Gleixner raw_spin_lock_irq(&cpu_buffer->reader_lock); 141083f40318SVaibhav Nagarnaik atomic_inc(&cpu_buffer->record_disabled); 141183f40318SVaibhav Nagarnaik /* 141283f40318SVaibhav Nagarnaik * We don't race with the readers since we have acquired the reader 141383f40318SVaibhav Nagarnaik * lock. We also don't race with writers after disabling recording. 141483f40318SVaibhav Nagarnaik * This makes it easy to figure out the first and the last page to be 141583f40318SVaibhav Nagarnaik * removed from the list. We unlink all the pages in between including 141683f40318SVaibhav Nagarnaik * the first and last pages. This is done in a busy loop so that we 141783f40318SVaibhav Nagarnaik * lose the least number of traces. 141883f40318SVaibhav Nagarnaik * The pages are freed after we restart recording and unlock readers. 141983f40318SVaibhav Nagarnaik */ 142083f40318SVaibhav Nagarnaik tail_page = &cpu_buffer->tail_page->list; 142177ae365eSSteven Rostedt 142283f40318SVaibhav Nagarnaik /* 142383f40318SVaibhav Nagarnaik * tail page might be on reader page, we remove the next page 142483f40318SVaibhav Nagarnaik * from the ring buffer 142583f40318SVaibhav Nagarnaik */ 142683f40318SVaibhav Nagarnaik if (cpu_buffer->tail_page == cpu_buffer->reader_page) 142783f40318SVaibhav Nagarnaik tail_page = rb_list_head(tail_page->next); 142883f40318SVaibhav Nagarnaik to_remove = tail_page; 142983f40318SVaibhav Nagarnaik 143083f40318SVaibhav Nagarnaik /* start of pages to remove */ 143183f40318SVaibhav Nagarnaik first_page = list_entry(rb_list_head(to_remove->next), 143283f40318SVaibhav Nagarnaik struct buffer_page, list); 143383f40318SVaibhav Nagarnaik 143483f40318SVaibhav Nagarnaik for (nr_removed = 0; nr_removed < nr_pages; nr_removed++) { 143583f40318SVaibhav Nagarnaik to_remove = rb_list_head(to_remove)->next; 143683f40318SVaibhav Nagarnaik head_bit |= (unsigned long)to_remove & RB_PAGE_HEAD; 14377a8e76a3SSteven Rostedt } 14387a8e76a3SSteven Rostedt 143983f40318SVaibhav Nagarnaik next_page = rb_list_head(to_remove)->next; 14407a8e76a3SSteven Rostedt 144183f40318SVaibhav Nagarnaik /* 144283f40318SVaibhav Nagarnaik * Now we remove all pages between tail_page and next_page. 144383f40318SVaibhav Nagarnaik * Make sure that we have head_bit value preserved for the 144483f40318SVaibhav Nagarnaik * next page 144583f40318SVaibhav Nagarnaik */ 144683f40318SVaibhav Nagarnaik tail_page->next = (struct list_head *)((unsigned long)next_page | 144783f40318SVaibhav Nagarnaik head_bit); 144883f40318SVaibhav Nagarnaik next_page = rb_list_head(next_page); 144983f40318SVaibhav Nagarnaik next_page->prev = tail_page; 145083f40318SVaibhav Nagarnaik 145183f40318SVaibhav Nagarnaik /* make sure pages points to a valid page in the ring buffer */ 145283f40318SVaibhav Nagarnaik cpu_buffer->pages = next_page; 145383f40318SVaibhav Nagarnaik 145483f40318SVaibhav Nagarnaik /* update head page */ 145583f40318SVaibhav Nagarnaik if (head_bit) 145683f40318SVaibhav Nagarnaik cpu_buffer->head_page = list_entry(next_page, 145783f40318SVaibhav Nagarnaik struct buffer_page, list); 145883f40318SVaibhav Nagarnaik 145983f40318SVaibhav Nagarnaik /* 146083f40318SVaibhav Nagarnaik * change read pointer to make sure any read iterators reset 146183f40318SVaibhav Nagarnaik * themselves 146283f40318SVaibhav Nagarnaik */ 146383f40318SVaibhav Nagarnaik cpu_buffer->read = 0; 146483f40318SVaibhav Nagarnaik 146583f40318SVaibhav Nagarnaik /* pages are removed, resume tracing and then free the pages */ 146683f40318SVaibhav Nagarnaik atomic_dec(&cpu_buffer->record_disabled); 14675389f6faSThomas Gleixner raw_spin_unlock_irq(&cpu_buffer->reader_lock); 146883f40318SVaibhav Nagarnaik 146983f40318SVaibhav Nagarnaik RB_WARN_ON(cpu_buffer, list_empty(cpu_buffer->pages)); 147083f40318SVaibhav Nagarnaik 147183f40318SVaibhav Nagarnaik /* last buffer page to remove */ 147283f40318SVaibhav Nagarnaik last_page = list_entry(rb_list_head(to_remove), struct buffer_page, 147383f40318SVaibhav Nagarnaik list); 147483f40318SVaibhav Nagarnaik tmp_iter_page = first_page; 147583f40318SVaibhav Nagarnaik 147683f40318SVaibhav Nagarnaik do { 147783f40318SVaibhav Nagarnaik to_remove_page = tmp_iter_page; 147883f40318SVaibhav Nagarnaik rb_inc_page(cpu_buffer, &tmp_iter_page); 147983f40318SVaibhav Nagarnaik 148083f40318SVaibhav Nagarnaik /* update the counters */ 148183f40318SVaibhav Nagarnaik page_entries = rb_page_entries(to_remove_page); 148283f40318SVaibhav Nagarnaik if (page_entries) { 148383f40318SVaibhav Nagarnaik /* 148483f40318SVaibhav Nagarnaik * If something was added to this page, it was full 148583f40318SVaibhav Nagarnaik * since it is not the tail page. So we deduct the 148683f40318SVaibhav Nagarnaik * bytes consumed in ring buffer from here. 148748fdc72fSVaibhav Nagarnaik * Increment overrun to account for the lost events. 148883f40318SVaibhav Nagarnaik */ 148948fdc72fSVaibhav Nagarnaik local_add(page_entries, &cpu_buffer->overrun); 149083f40318SVaibhav Nagarnaik local_sub(BUF_PAGE_SIZE, &cpu_buffer->entries_bytes); 149183f40318SVaibhav Nagarnaik } 149283f40318SVaibhav Nagarnaik 149383f40318SVaibhav Nagarnaik /* 149483f40318SVaibhav Nagarnaik * We have already removed references to this list item, just 149583f40318SVaibhav Nagarnaik * free up the buffer_page and its page 149683f40318SVaibhav Nagarnaik */ 149783f40318SVaibhav Nagarnaik free_buffer_page(to_remove_page); 149883f40318SVaibhav Nagarnaik nr_removed--; 149983f40318SVaibhav Nagarnaik 150083f40318SVaibhav Nagarnaik } while (to_remove_page != last_page); 150183f40318SVaibhav Nagarnaik 150283f40318SVaibhav Nagarnaik RB_WARN_ON(cpu_buffer, nr_removed); 15035040b4b7SVaibhav Nagarnaik 15045040b4b7SVaibhav Nagarnaik return nr_removed == 0; 15057a8e76a3SSteven Rostedt } 15067a8e76a3SSteven Rostedt 15075040b4b7SVaibhav Nagarnaik static int 15085040b4b7SVaibhav Nagarnaik rb_insert_pages(struct ring_buffer_per_cpu *cpu_buffer) 15097a8e76a3SSteven Rostedt { 15105040b4b7SVaibhav Nagarnaik struct list_head *pages = &cpu_buffer->new_pages; 15115040b4b7SVaibhav Nagarnaik int retries, success; 15127a8e76a3SSteven Rostedt 15135389f6faSThomas Gleixner raw_spin_lock_irq(&cpu_buffer->reader_lock); 15145040b4b7SVaibhav Nagarnaik /* 15155040b4b7SVaibhav Nagarnaik * We are holding the reader lock, so the reader page won't be swapped 15165040b4b7SVaibhav Nagarnaik * in the ring buffer. Now we are racing with the writer trying to 15175040b4b7SVaibhav Nagarnaik * move head page and the tail page. 15185040b4b7SVaibhav Nagarnaik * We are going to adapt the reader page update process where: 15195040b4b7SVaibhav Nagarnaik * 1. We first splice the start and end of list of new pages between 15205040b4b7SVaibhav Nagarnaik * the head page and its previous page. 15215040b4b7SVaibhav Nagarnaik * 2. We cmpxchg the prev_page->next to point from head page to the 15225040b4b7SVaibhav Nagarnaik * start of new pages list. 15235040b4b7SVaibhav Nagarnaik * 3. Finally, we update the head->prev to the end of new list. 15245040b4b7SVaibhav Nagarnaik * 15255040b4b7SVaibhav Nagarnaik * We will try this process 10 times, to make sure that we don't keep 15265040b4b7SVaibhav Nagarnaik * spinning. 15275040b4b7SVaibhav Nagarnaik */ 15285040b4b7SVaibhav Nagarnaik retries = 10; 15295040b4b7SVaibhav Nagarnaik success = 0; 15305040b4b7SVaibhav Nagarnaik while (retries--) { 15315040b4b7SVaibhav Nagarnaik struct list_head *head_page, *prev_page, *r; 15325040b4b7SVaibhav Nagarnaik struct list_head *last_page, *first_page; 15335040b4b7SVaibhav Nagarnaik struct list_head *head_page_with_bit; 153477ae365eSSteven Rostedt 15355040b4b7SVaibhav Nagarnaik head_page = &rb_set_head_page(cpu_buffer)->list; 153654f7be5bSSteven Rostedt if (!head_page) 153754f7be5bSSteven Rostedt break; 15385040b4b7SVaibhav Nagarnaik prev_page = head_page->prev; 15395040b4b7SVaibhav Nagarnaik 15405040b4b7SVaibhav Nagarnaik first_page = pages->next; 15415040b4b7SVaibhav Nagarnaik last_page = pages->prev; 15425040b4b7SVaibhav Nagarnaik 15435040b4b7SVaibhav Nagarnaik head_page_with_bit = (struct list_head *) 15445040b4b7SVaibhav Nagarnaik ((unsigned long)head_page | RB_PAGE_HEAD); 15455040b4b7SVaibhav Nagarnaik 15465040b4b7SVaibhav Nagarnaik last_page->next = head_page_with_bit; 15475040b4b7SVaibhav Nagarnaik first_page->prev = prev_page; 15485040b4b7SVaibhav Nagarnaik 15495040b4b7SVaibhav Nagarnaik r = cmpxchg(&prev_page->next, head_page_with_bit, first_page); 15505040b4b7SVaibhav Nagarnaik 15515040b4b7SVaibhav Nagarnaik if (r == head_page_with_bit) { 15525040b4b7SVaibhav Nagarnaik /* 15535040b4b7SVaibhav Nagarnaik * yay, we replaced the page pointer to our new list, 15545040b4b7SVaibhav Nagarnaik * now, we just have to update to head page's prev 15555040b4b7SVaibhav Nagarnaik * pointer to point to end of list 15565040b4b7SVaibhav Nagarnaik */ 15575040b4b7SVaibhav Nagarnaik head_page->prev = last_page; 15585040b4b7SVaibhav Nagarnaik success = 1; 15595040b4b7SVaibhav Nagarnaik break; 15607a8e76a3SSteven Rostedt } 15615040b4b7SVaibhav Nagarnaik } 15627a8e76a3SSteven Rostedt 15635040b4b7SVaibhav Nagarnaik if (success) 15645040b4b7SVaibhav Nagarnaik INIT_LIST_HEAD(pages); 15655040b4b7SVaibhav Nagarnaik /* 15665040b4b7SVaibhav Nagarnaik * If we weren't successful in adding in new pages, warn and stop 15675040b4b7SVaibhav Nagarnaik * tracing 15685040b4b7SVaibhav Nagarnaik */ 15695040b4b7SVaibhav Nagarnaik RB_WARN_ON(cpu_buffer, !success); 15705389f6faSThomas Gleixner raw_spin_unlock_irq(&cpu_buffer->reader_lock); 15715040b4b7SVaibhav Nagarnaik 15725040b4b7SVaibhav Nagarnaik /* free pages if they weren't inserted */ 15735040b4b7SVaibhav Nagarnaik if (!success) { 15745040b4b7SVaibhav Nagarnaik struct buffer_page *bpage, *tmp; 15755040b4b7SVaibhav Nagarnaik list_for_each_entry_safe(bpage, tmp, &cpu_buffer->new_pages, 15765040b4b7SVaibhav Nagarnaik list) { 15775040b4b7SVaibhav Nagarnaik list_del_init(&bpage->list); 15785040b4b7SVaibhav Nagarnaik free_buffer_page(bpage); 15795040b4b7SVaibhav Nagarnaik } 15805040b4b7SVaibhav Nagarnaik } 15815040b4b7SVaibhav Nagarnaik return success; 15827a8e76a3SSteven Rostedt } 15837a8e76a3SSteven Rostedt 158483f40318SVaibhav Nagarnaik static void rb_update_pages(struct ring_buffer_per_cpu *cpu_buffer) 1585438ced17SVaibhav Nagarnaik { 15865040b4b7SVaibhav Nagarnaik int success; 158783f40318SVaibhav Nagarnaik 15885040b4b7SVaibhav Nagarnaik if (cpu_buffer->nr_pages_to_update > 0) 15895040b4b7SVaibhav Nagarnaik success = rb_insert_pages(cpu_buffer); 15905040b4b7SVaibhav Nagarnaik else 15915040b4b7SVaibhav Nagarnaik success = rb_remove_pages(cpu_buffer, 15925040b4b7SVaibhav Nagarnaik -cpu_buffer->nr_pages_to_update); 15935040b4b7SVaibhav Nagarnaik 15945040b4b7SVaibhav Nagarnaik if (success) 1595438ced17SVaibhav Nagarnaik cpu_buffer->nr_pages += cpu_buffer->nr_pages_to_update; 159683f40318SVaibhav Nagarnaik } 159783f40318SVaibhav Nagarnaik 159883f40318SVaibhav Nagarnaik static void update_pages_handler(struct work_struct *work) 159983f40318SVaibhav Nagarnaik { 160083f40318SVaibhav Nagarnaik struct ring_buffer_per_cpu *cpu_buffer = container_of(work, 160183f40318SVaibhav Nagarnaik struct ring_buffer_per_cpu, update_pages_work); 160283f40318SVaibhav Nagarnaik rb_update_pages(cpu_buffer); 160305fdd70dSVaibhav Nagarnaik complete(&cpu_buffer->update_done); 1604438ced17SVaibhav Nagarnaik } 1605438ced17SVaibhav Nagarnaik 16067a8e76a3SSteven Rostedt /** 16077a8e76a3SSteven Rostedt * ring_buffer_resize - resize the ring buffer 16087a8e76a3SSteven Rostedt * @buffer: the buffer to resize. 16097a8e76a3SSteven Rostedt * @size: the new size. 1610d611851bSzhangwei(Jovi) * @cpu_id: the cpu buffer to resize 16117a8e76a3SSteven Rostedt * 16127a8e76a3SSteven Rostedt * Minimum size is 2 * BUF_PAGE_SIZE. 16137a8e76a3SSteven Rostedt * 161483f40318SVaibhav Nagarnaik * Returns 0 on success and < 0 on failure. 16157a8e76a3SSteven Rostedt */ 1616438ced17SVaibhav Nagarnaik int ring_buffer_resize(struct ring_buffer *buffer, unsigned long size, 1617438ced17SVaibhav Nagarnaik int cpu_id) 16187a8e76a3SSteven Rostedt { 16197a8e76a3SSteven Rostedt struct ring_buffer_per_cpu *cpu_buffer; 16209b94a8fbSSteven Rostedt (Red Hat) unsigned long nr_pages; 162183f40318SVaibhav Nagarnaik int cpu, err = 0; 16227a8e76a3SSteven Rostedt 1623ee51a1deSIngo Molnar /* 1624ee51a1deSIngo Molnar * Always succeed at resizing a non-existent buffer: 1625ee51a1deSIngo Molnar */ 1626ee51a1deSIngo Molnar if (!buffer) 1627ee51a1deSIngo Molnar return size; 1628ee51a1deSIngo Molnar 16296a31e1f1SSteven Rostedt /* Make sure the requested buffer exists */ 16306a31e1f1SSteven Rostedt if (cpu_id != RING_BUFFER_ALL_CPUS && 16316a31e1f1SSteven Rostedt !cpumask_test_cpu(cpu_id, buffer->cpumask)) 16326a31e1f1SSteven Rostedt return size; 16336a31e1f1SSteven Rostedt 163459643d15SSteven Rostedt (Red Hat) nr_pages = DIV_ROUND_UP(size, BUF_PAGE_SIZE); 16357a8e76a3SSteven Rostedt 16367a8e76a3SSteven Rostedt /* we need a minimum of two pages */ 163759643d15SSteven Rostedt (Red Hat) if (nr_pages < 2) 163859643d15SSteven Rostedt (Red Hat) nr_pages = 2; 16397a8e76a3SSteven Rostedt 164059643d15SSteven Rostedt (Red Hat) size = nr_pages * BUF_PAGE_SIZE; 16417a8e76a3SSteven Rostedt 164283f40318SVaibhav Nagarnaik /* 164383f40318SVaibhav Nagarnaik * Don't succeed if resizing is disabled, as a reader might be 164483f40318SVaibhav Nagarnaik * manipulating the ring buffer and is expecting a sane state while 164583f40318SVaibhav Nagarnaik * this is true. 164683f40318SVaibhav Nagarnaik */ 164783f40318SVaibhav Nagarnaik if (atomic_read(&buffer->resize_disabled)) 164883f40318SVaibhav Nagarnaik return -EBUSY; 164983f40318SVaibhav Nagarnaik 165083f40318SVaibhav Nagarnaik /* prevent another thread from changing buffer sizes */ 165183f40318SVaibhav Nagarnaik mutex_lock(&buffer->mutex); 165283f40318SVaibhav Nagarnaik 1653438ced17SVaibhav Nagarnaik if (cpu_id == RING_BUFFER_ALL_CPUS) { 1654438ced17SVaibhav Nagarnaik /* calculate the pages to update */ 16557a8e76a3SSteven Rostedt for_each_buffer_cpu(buffer, cpu) { 16567a8e76a3SSteven Rostedt cpu_buffer = buffer->buffers[cpu]; 1657438ced17SVaibhav Nagarnaik 1658438ced17SVaibhav Nagarnaik cpu_buffer->nr_pages_to_update = nr_pages - 1659438ced17SVaibhav Nagarnaik cpu_buffer->nr_pages; 1660438ced17SVaibhav Nagarnaik /* 1661438ced17SVaibhav Nagarnaik * nothing more to do for removing pages or no update 1662438ced17SVaibhav Nagarnaik */ 1663438ced17SVaibhav Nagarnaik if (cpu_buffer->nr_pages_to_update <= 0) 1664438ced17SVaibhav Nagarnaik continue; 1665438ced17SVaibhav Nagarnaik /* 1666438ced17SVaibhav Nagarnaik * to add pages, make sure all new pages can be 1667438ced17SVaibhav Nagarnaik * allocated without receiving ENOMEM 1668438ced17SVaibhav Nagarnaik */ 1669438ced17SVaibhav Nagarnaik INIT_LIST_HEAD(&cpu_buffer->new_pages); 1670438ced17SVaibhav Nagarnaik if (__rb_allocate_pages(cpu_buffer->nr_pages_to_update, 167183f40318SVaibhav Nagarnaik &cpu_buffer->new_pages, cpu)) { 1672438ced17SVaibhav Nagarnaik /* not enough memory for new pages */ 167383f40318SVaibhav Nagarnaik err = -ENOMEM; 167483f40318SVaibhav Nagarnaik goto out_err; 167583f40318SVaibhav Nagarnaik } 167683f40318SVaibhav Nagarnaik } 167783f40318SVaibhav Nagarnaik 167883f40318SVaibhav Nagarnaik get_online_cpus(); 167983f40318SVaibhav Nagarnaik /* 168083f40318SVaibhav Nagarnaik * Fire off all the required work handlers 168105fdd70dSVaibhav Nagarnaik * We can't schedule on offline CPUs, but it's not necessary 168283f40318SVaibhav Nagarnaik * since we can change their buffer sizes without any race. 168383f40318SVaibhav Nagarnaik */ 168483f40318SVaibhav Nagarnaik for_each_buffer_cpu(buffer, cpu) { 168583f40318SVaibhav Nagarnaik cpu_buffer = buffer->buffers[cpu]; 168605fdd70dSVaibhav Nagarnaik if (!cpu_buffer->nr_pages_to_update) 168783f40318SVaibhav Nagarnaik continue; 168883f40318SVaibhav Nagarnaik 1689021c5b34SCorey Minyard /* Can't run something on an offline CPU. */ 1690021c5b34SCorey Minyard if (!cpu_online(cpu)) { 1691f5eb5588SSteven Rostedt (Red Hat) rb_update_pages(cpu_buffer); 1692f5eb5588SSteven Rostedt (Red Hat) cpu_buffer->nr_pages_to_update = 0; 1693f5eb5588SSteven Rostedt (Red Hat) } else { 169405fdd70dSVaibhav Nagarnaik schedule_work_on(cpu, 169505fdd70dSVaibhav Nagarnaik &cpu_buffer->update_pages_work); 1696f5eb5588SSteven Rostedt (Red Hat) } 16977a8e76a3SSteven Rostedt } 1698438ced17SVaibhav Nagarnaik 1699438ced17SVaibhav Nagarnaik /* wait for all the updates to complete */ 1700438ced17SVaibhav Nagarnaik for_each_buffer_cpu(buffer, cpu) { 1701438ced17SVaibhav Nagarnaik cpu_buffer = buffer->buffers[cpu]; 170205fdd70dSVaibhav Nagarnaik if (!cpu_buffer->nr_pages_to_update) 170383f40318SVaibhav Nagarnaik continue; 170483f40318SVaibhav Nagarnaik 170505fdd70dSVaibhav Nagarnaik if (cpu_online(cpu)) 170605fdd70dSVaibhav Nagarnaik wait_for_completion(&cpu_buffer->update_done); 170783f40318SVaibhav Nagarnaik cpu_buffer->nr_pages_to_update = 0; 1708438ced17SVaibhav Nagarnaik } 170983f40318SVaibhav Nagarnaik 171083f40318SVaibhav Nagarnaik put_online_cpus(); 1711438ced17SVaibhav Nagarnaik } else { 17128e49f418SVaibhav Nagarnaik /* Make sure this CPU has been intitialized */ 17138e49f418SVaibhav Nagarnaik if (!cpumask_test_cpu(cpu_id, buffer->cpumask)) 17148e49f418SVaibhav Nagarnaik goto out; 17158e49f418SVaibhav Nagarnaik 1716438ced17SVaibhav Nagarnaik cpu_buffer = buffer->buffers[cpu_id]; 171783f40318SVaibhav Nagarnaik 1718438ced17SVaibhav Nagarnaik if (nr_pages == cpu_buffer->nr_pages) 17197a8e76a3SSteven Rostedt goto out; 1720438ced17SVaibhav Nagarnaik 1721438ced17SVaibhav Nagarnaik cpu_buffer->nr_pages_to_update = nr_pages - 1722438ced17SVaibhav Nagarnaik cpu_buffer->nr_pages; 1723438ced17SVaibhav Nagarnaik 1724438ced17SVaibhav Nagarnaik INIT_LIST_HEAD(&cpu_buffer->new_pages); 1725438ced17SVaibhav Nagarnaik if (cpu_buffer->nr_pages_to_update > 0 && 1726438ced17SVaibhav Nagarnaik __rb_allocate_pages(cpu_buffer->nr_pages_to_update, 172783f40318SVaibhav Nagarnaik &cpu_buffer->new_pages, cpu_id)) { 172883f40318SVaibhav Nagarnaik err = -ENOMEM; 172983f40318SVaibhav Nagarnaik goto out_err; 173083f40318SVaibhav Nagarnaik } 1731438ced17SVaibhav Nagarnaik 173283f40318SVaibhav Nagarnaik get_online_cpus(); 173383f40318SVaibhav Nagarnaik 1734021c5b34SCorey Minyard /* Can't run something on an offline CPU. */ 1735021c5b34SCorey Minyard if (!cpu_online(cpu_id)) 1736f5eb5588SSteven Rostedt (Red Hat) rb_update_pages(cpu_buffer); 1737f5eb5588SSteven Rostedt (Red Hat) else { 173883f40318SVaibhav Nagarnaik schedule_work_on(cpu_id, 173983f40318SVaibhav Nagarnaik &cpu_buffer->update_pages_work); 174005fdd70dSVaibhav Nagarnaik wait_for_completion(&cpu_buffer->update_done); 1741f5eb5588SSteven Rostedt (Red Hat) } 174283f40318SVaibhav Nagarnaik 174383f40318SVaibhav Nagarnaik cpu_buffer->nr_pages_to_update = 0; 174405fdd70dSVaibhav Nagarnaik put_online_cpus(); 17457a8e76a3SSteven Rostedt } 17467a8e76a3SSteven Rostedt 17477a8e76a3SSteven Rostedt out: 1748659f451fSSteven Rostedt /* 1749659f451fSSteven Rostedt * The ring buffer resize can happen with the ring buffer 1750659f451fSSteven Rostedt * enabled, so that the update disturbs the tracing as little 1751659f451fSSteven Rostedt * as possible. But if the buffer is disabled, we do not need 1752659f451fSSteven Rostedt * to worry about that, and we can take the time to verify 1753659f451fSSteven Rostedt * that the buffer is not corrupt. 1754659f451fSSteven Rostedt */ 1755659f451fSSteven Rostedt if (atomic_read(&buffer->record_disabled)) { 1756659f451fSSteven Rostedt atomic_inc(&buffer->record_disabled); 1757659f451fSSteven Rostedt /* 1758659f451fSSteven Rostedt * Even though the buffer was disabled, we must make sure 1759659f451fSSteven Rostedt * that it is truly disabled before calling rb_check_pages. 1760659f451fSSteven Rostedt * There could have been a race between checking 1761659f451fSSteven Rostedt * record_disable and incrementing it. 1762659f451fSSteven Rostedt */ 1763659f451fSSteven Rostedt synchronize_sched(); 1764659f451fSSteven Rostedt for_each_buffer_cpu(buffer, cpu) { 1765659f451fSSteven Rostedt cpu_buffer = buffer->buffers[cpu]; 1766659f451fSSteven Rostedt rb_check_pages(cpu_buffer); 1767659f451fSSteven Rostedt } 1768659f451fSSteven Rostedt atomic_dec(&buffer->record_disabled); 1769659f451fSSteven Rostedt } 1770659f451fSSteven Rostedt 17717a8e76a3SSteven Rostedt mutex_unlock(&buffer->mutex); 17727a8e76a3SSteven Rostedt return size; 17737a8e76a3SSteven Rostedt 177483f40318SVaibhav Nagarnaik out_err: 1775438ced17SVaibhav Nagarnaik for_each_buffer_cpu(buffer, cpu) { 1776438ced17SVaibhav Nagarnaik struct buffer_page *bpage, *tmp; 177783f40318SVaibhav Nagarnaik 1778438ced17SVaibhav Nagarnaik cpu_buffer = buffer->buffers[cpu]; 1779438ced17SVaibhav Nagarnaik cpu_buffer->nr_pages_to_update = 0; 178083f40318SVaibhav Nagarnaik 1781438ced17SVaibhav Nagarnaik if (list_empty(&cpu_buffer->new_pages)) 1782438ced17SVaibhav Nagarnaik continue; 178383f40318SVaibhav Nagarnaik 1784438ced17SVaibhav Nagarnaik list_for_each_entry_safe(bpage, tmp, &cpu_buffer->new_pages, 1785438ced17SVaibhav Nagarnaik list) { 1786044fa782SSteven Rostedt list_del_init(&bpage->list); 1787044fa782SSteven Rostedt free_buffer_page(bpage); 17887a8e76a3SSteven Rostedt } 1789438ced17SVaibhav Nagarnaik } 1790641d2f63SVegard Nossum mutex_unlock(&buffer->mutex); 179183f40318SVaibhav Nagarnaik return err; 17927a8e76a3SSteven Rostedt } 1793c4f50183SRobert Richter EXPORT_SYMBOL_GPL(ring_buffer_resize); 17947a8e76a3SSteven Rostedt 1795750912faSDavid Sharp void ring_buffer_change_overwrite(struct ring_buffer *buffer, int val) 1796750912faSDavid Sharp { 1797750912faSDavid Sharp mutex_lock(&buffer->mutex); 1798750912faSDavid Sharp if (val) 1799750912faSDavid Sharp buffer->flags |= RB_FL_OVERWRITE; 1800750912faSDavid Sharp else 1801750912faSDavid Sharp buffer->flags &= ~RB_FL_OVERWRITE; 1802750912faSDavid Sharp mutex_unlock(&buffer->mutex); 1803750912faSDavid Sharp } 1804750912faSDavid Sharp EXPORT_SYMBOL_GPL(ring_buffer_change_overwrite); 1805750912faSDavid Sharp 18062289d567SSteven Rostedt (Red Hat) static __always_inline void *__rb_page_index(struct buffer_page *bpage, unsigned index) 18077a8e76a3SSteven Rostedt { 1808044fa782SSteven Rostedt return bpage->page->data + index; 18097a8e76a3SSteven Rostedt } 18107a8e76a3SSteven Rostedt 18112289d567SSteven Rostedt (Red Hat) static __always_inline struct ring_buffer_event * 1812d769041fSSteven Rostedt rb_reader_event(struct ring_buffer_per_cpu *cpu_buffer) 18137a8e76a3SSteven Rostedt { 18146f807acdSSteven Rostedt return __rb_page_index(cpu_buffer->reader_page, 18156f807acdSSteven Rostedt cpu_buffer->reader_page->read); 18166f807acdSSteven Rostedt } 18176f807acdSSteven Rostedt 18182289d567SSteven Rostedt (Red Hat) static __always_inline struct ring_buffer_event * 18197a8e76a3SSteven Rostedt rb_iter_head_event(struct ring_buffer_iter *iter) 18207a8e76a3SSteven Rostedt { 18216f807acdSSteven Rostedt return __rb_page_index(iter->head_page, iter->head); 18227a8e76a3SSteven Rostedt } 18237a8e76a3SSteven Rostedt 18242289d567SSteven Rostedt (Red Hat) static __always_inline unsigned rb_page_commit(struct buffer_page *bpage) 1825bf41a158SSteven Rostedt { 1826abc9b56dSSteven Rostedt return local_read(&bpage->page->commit); 1827bf41a158SSteven Rostedt } 1828bf41a158SSteven Rostedt 182925985edcSLucas De Marchi /* Size is determined by what has been committed */ 18302289d567SSteven Rostedt (Red Hat) static __always_inline unsigned rb_page_size(struct buffer_page *bpage) 1831bf41a158SSteven Rostedt { 1832bf41a158SSteven Rostedt return rb_page_commit(bpage); 1833bf41a158SSteven Rostedt } 1834bf41a158SSteven Rostedt 18352289d567SSteven Rostedt (Red Hat) static __always_inline unsigned 1836bf41a158SSteven Rostedt rb_commit_index(struct ring_buffer_per_cpu *cpu_buffer) 1837bf41a158SSteven Rostedt { 1838bf41a158SSteven Rostedt return rb_page_commit(cpu_buffer->commit_page); 1839bf41a158SSteven Rostedt } 1840bf41a158SSteven Rostedt 18412289d567SSteven Rostedt (Red Hat) static __always_inline unsigned 1842bf41a158SSteven Rostedt rb_event_index(struct ring_buffer_event *event) 18437a8e76a3SSteven Rostedt { 1844bf41a158SSteven Rostedt unsigned long addr = (unsigned long)event; 1845bf41a158SSteven Rostedt 184622f470f8SSteven Rostedt return (addr & ~PAGE_MASK) - BUF_PAGE_HDR_SIZE; 18477a8e76a3SSteven Rostedt } 18487a8e76a3SSteven Rostedt 184934a148bfSAndrew Morton static void rb_inc_iter(struct ring_buffer_iter *iter) 1850d769041fSSteven Rostedt { 1851d769041fSSteven Rostedt struct ring_buffer_per_cpu *cpu_buffer = iter->cpu_buffer; 1852d769041fSSteven Rostedt 1853d769041fSSteven Rostedt /* 1854d769041fSSteven Rostedt * The iterator could be on the reader page (it starts there). 1855d769041fSSteven Rostedt * But the head could have moved, since the reader was 1856d769041fSSteven Rostedt * found. Check for this case and assign the iterator 1857d769041fSSteven Rostedt * to the head page instead of next. 1858d769041fSSteven Rostedt */ 1859d769041fSSteven Rostedt if (iter->head_page == cpu_buffer->reader_page) 186077ae365eSSteven Rostedt iter->head_page = rb_set_head_page(cpu_buffer); 1861d769041fSSteven Rostedt else 1862d769041fSSteven Rostedt rb_inc_page(cpu_buffer, &iter->head_page); 1863d769041fSSteven Rostedt 1864abc9b56dSSteven Rostedt iter->read_stamp = iter->head_page->page->time_stamp; 18657a8e76a3SSteven Rostedt iter->head = 0; 18667a8e76a3SSteven Rostedt } 18677a8e76a3SSteven Rostedt 186877ae365eSSteven Rostedt /* 186977ae365eSSteven Rostedt * rb_handle_head_page - writer hit the head page 187077ae365eSSteven Rostedt * 187177ae365eSSteven Rostedt * Returns: +1 to retry page 187277ae365eSSteven Rostedt * 0 to continue 187377ae365eSSteven Rostedt * -1 on error 187477ae365eSSteven Rostedt */ 187577ae365eSSteven Rostedt static int 187677ae365eSSteven Rostedt rb_handle_head_page(struct ring_buffer_per_cpu *cpu_buffer, 187777ae365eSSteven Rostedt struct buffer_page *tail_page, 187877ae365eSSteven Rostedt struct buffer_page *next_page) 187977ae365eSSteven Rostedt { 188077ae365eSSteven Rostedt struct buffer_page *new_head; 188177ae365eSSteven Rostedt int entries; 188277ae365eSSteven Rostedt int type; 188377ae365eSSteven Rostedt int ret; 188477ae365eSSteven Rostedt 188577ae365eSSteven Rostedt entries = rb_page_entries(next_page); 188677ae365eSSteven Rostedt 188777ae365eSSteven Rostedt /* 188877ae365eSSteven Rostedt * The hard part is here. We need to move the head 188977ae365eSSteven Rostedt * forward, and protect against both readers on 189077ae365eSSteven Rostedt * other CPUs and writers coming in via interrupts. 189177ae365eSSteven Rostedt */ 189277ae365eSSteven Rostedt type = rb_head_page_set_update(cpu_buffer, next_page, tail_page, 189377ae365eSSteven Rostedt RB_PAGE_HEAD); 189477ae365eSSteven Rostedt 189577ae365eSSteven Rostedt /* 189677ae365eSSteven Rostedt * type can be one of four: 189777ae365eSSteven Rostedt * NORMAL - an interrupt already moved it for us 189877ae365eSSteven Rostedt * HEAD - we are the first to get here. 189977ae365eSSteven Rostedt * UPDATE - we are the interrupt interrupting 190077ae365eSSteven Rostedt * a current move. 190177ae365eSSteven Rostedt * MOVED - a reader on another CPU moved the next 190277ae365eSSteven Rostedt * pointer to its reader page. Give up 190377ae365eSSteven Rostedt * and try again. 190477ae365eSSteven Rostedt */ 190577ae365eSSteven Rostedt 190677ae365eSSteven Rostedt switch (type) { 190777ae365eSSteven Rostedt case RB_PAGE_HEAD: 190877ae365eSSteven Rostedt /* 190977ae365eSSteven Rostedt * We changed the head to UPDATE, thus 191077ae365eSSteven Rostedt * it is our responsibility to update 191177ae365eSSteven Rostedt * the counters. 191277ae365eSSteven Rostedt */ 191377ae365eSSteven Rostedt local_add(entries, &cpu_buffer->overrun); 1914c64e148aSVaibhav Nagarnaik local_sub(BUF_PAGE_SIZE, &cpu_buffer->entries_bytes); 191577ae365eSSteven Rostedt 191677ae365eSSteven Rostedt /* 191777ae365eSSteven Rostedt * The entries will be zeroed out when we move the 191877ae365eSSteven Rostedt * tail page. 191977ae365eSSteven Rostedt */ 192077ae365eSSteven Rostedt 192177ae365eSSteven Rostedt /* still more to do */ 192277ae365eSSteven Rostedt break; 192377ae365eSSteven Rostedt 192477ae365eSSteven Rostedt case RB_PAGE_UPDATE: 192577ae365eSSteven Rostedt /* 192677ae365eSSteven Rostedt * This is an interrupt that interrupt the 192777ae365eSSteven Rostedt * previous update. Still more to do. 192877ae365eSSteven Rostedt */ 192977ae365eSSteven Rostedt break; 193077ae365eSSteven Rostedt case RB_PAGE_NORMAL: 193177ae365eSSteven Rostedt /* 193277ae365eSSteven Rostedt * An interrupt came in before the update 193377ae365eSSteven Rostedt * and processed this for us. 193477ae365eSSteven Rostedt * Nothing left to do. 193577ae365eSSteven Rostedt */ 193677ae365eSSteven Rostedt return 1; 193777ae365eSSteven Rostedt case RB_PAGE_MOVED: 193877ae365eSSteven Rostedt /* 193977ae365eSSteven Rostedt * The reader is on another CPU and just did 194077ae365eSSteven Rostedt * a swap with our next_page. 194177ae365eSSteven Rostedt * Try again. 194277ae365eSSteven Rostedt */ 194377ae365eSSteven Rostedt return 1; 194477ae365eSSteven Rostedt default: 194577ae365eSSteven Rostedt RB_WARN_ON(cpu_buffer, 1); /* WTF??? */ 194677ae365eSSteven Rostedt return -1; 194777ae365eSSteven Rostedt } 194877ae365eSSteven Rostedt 194977ae365eSSteven Rostedt /* 195077ae365eSSteven Rostedt * Now that we are here, the old head pointer is 195177ae365eSSteven Rostedt * set to UPDATE. This will keep the reader from 195277ae365eSSteven Rostedt * swapping the head page with the reader page. 195377ae365eSSteven Rostedt * The reader (on another CPU) will spin till 195477ae365eSSteven Rostedt * we are finished. 195577ae365eSSteven Rostedt * 195677ae365eSSteven Rostedt * We just need to protect against interrupts 195777ae365eSSteven Rostedt * doing the job. We will set the next pointer 195877ae365eSSteven Rostedt * to HEAD. After that, we set the old pointer 195977ae365eSSteven Rostedt * to NORMAL, but only if it was HEAD before. 196077ae365eSSteven Rostedt * otherwise we are an interrupt, and only 196177ae365eSSteven Rostedt * want the outer most commit to reset it. 196277ae365eSSteven Rostedt */ 196377ae365eSSteven Rostedt new_head = next_page; 196477ae365eSSteven Rostedt rb_inc_page(cpu_buffer, &new_head); 196577ae365eSSteven Rostedt 196677ae365eSSteven Rostedt ret = rb_head_page_set_head(cpu_buffer, new_head, next_page, 196777ae365eSSteven Rostedt RB_PAGE_NORMAL); 196877ae365eSSteven Rostedt 196977ae365eSSteven Rostedt /* 197077ae365eSSteven Rostedt * Valid returns are: 197177ae365eSSteven Rostedt * HEAD - an interrupt came in and already set it. 197277ae365eSSteven Rostedt * NORMAL - One of two things: 197377ae365eSSteven Rostedt * 1) We really set it. 197477ae365eSSteven Rostedt * 2) A bunch of interrupts came in and moved 197577ae365eSSteven Rostedt * the page forward again. 197677ae365eSSteven Rostedt */ 197777ae365eSSteven Rostedt switch (ret) { 197877ae365eSSteven Rostedt case RB_PAGE_HEAD: 197977ae365eSSteven Rostedt case RB_PAGE_NORMAL: 198077ae365eSSteven Rostedt /* OK */ 198177ae365eSSteven Rostedt break; 198277ae365eSSteven Rostedt default: 198377ae365eSSteven Rostedt RB_WARN_ON(cpu_buffer, 1); 198477ae365eSSteven Rostedt return -1; 198577ae365eSSteven Rostedt } 198677ae365eSSteven Rostedt 198777ae365eSSteven Rostedt /* 198877ae365eSSteven Rostedt * It is possible that an interrupt came in, 198977ae365eSSteven Rostedt * set the head up, then more interrupts came in 199077ae365eSSteven Rostedt * and moved it again. When we get back here, 199177ae365eSSteven Rostedt * the page would have been set to NORMAL but we 199277ae365eSSteven Rostedt * just set it back to HEAD. 199377ae365eSSteven Rostedt * 199477ae365eSSteven Rostedt * How do you detect this? Well, if that happened 199577ae365eSSteven Rostedt * the tail page would have moved. 199677ae365eSSteven Rostedt */ 199777ae365eSSteven Rostedt if (ret == RB_PAGE_NORMAL) { 19988573636eSSteven Rostedt (Red Hat) struct buffer_page *buffer_tail_page; 19998573636eSSteven Rostedt (Red Hat) 20008573636eSSteven Rostedt (Red Hat) buffer_tail_page = READ_ONCE(cpu_buffer->tail_page); 200177ae365eSSteven Rostedt /* 200277ae365eSSteven Rostedt * If the tail had moved passed next, then we need 200377ae365eSSteven Rostedt * to reset the pointer. 200477ae365eSSteven Rostedt */ 20058573636eSSteven Rostedt (Red Hat) if (buffer_tail_page != tail_page && 20068573636eSSteven Rostedt (Red Hat) buffer_tail_page != next_page) 200777ae365eSSteven Rostedt rb_head_page_set_normal(cpu_buffer, new_head, 200877ae365eSSteven Rostedt next_page, 200977ae365eSSteven Rostedt RB_PAGE_HEAD); 201077ae365eSSteven Rostedt } 201177ae365eSSteven Rostedt 201277ae365eSSteven Rostedt /* 201377ae365eSSteven Rostedt * If this was the outer most commit (the one that 201477ae365eSSteven Rostedt * changed the original pointer from HEAD to UPDATE), 201577ae365eSSteven Rostedt * then it is up to us to reset it to NORMAL. 201677ae365eSSteven Rostedt */ 201777ae365eSSteven Rostedt if (type == RB_PAGE_HEAD) { 201877ae365eSSteven Rostedt ret = rb_head_page_set_normal(cpu_buffer, next_page, 201977ae365eSSteven Rostedt tail_page, 202077ae365eSSteven Rostedt RB_PAGE_UPDATE); 202177ae365eSSteven Rostedt if (RB_WARN_ON(cpu_buffer, 202277ae365eSSteven Rostedt ret != RB_PAGE_UPDATE)) 202377ae365eSSteven Rostedt return -1; 202477ae365eSSteven Rostedt } 202577ae365eSSteven Rostedt 202677ae365eSSteven Rostedt return 0; 202777ae365eSSteven Rostedt } 202877ae365eSSteven Rostedt 2029c7b09308SSteven Rostedt static inline void 2030c7b09308SSteven Rostedt rb_reset_tail(struct ring_buffer_per_cpu *cpu_buffer, 2031fcc742eaSSteven Rostedt (Red Hat) unsigned long tail, struct rb_event_info *info) 2032c7b09308SSteven Rostedt { 2033fcc742eaSSteven Rostedt (Red Hat) struct buffer_page *tail_page = info->tail_page; 2034c7b09308SSteven Rostedt struct ring_buffer_event *event; 2035fcc742eaSSteven Rostedt (Red Hat) unsigned long length = info->length; 2036c7b09308SSteven Rostedt 2037c7b09308SSteven Rostedt /* 2038c7b09308SSteven Rostedt * Only the event that crossed the page boundary 2039c7b09308SSteven Rostedt * must fill the old tail_page with padding. 2040c7b09308SSteven Rostedt */ 2041c7b09308SSteven Rostedt if (tail >= BUF_PAGE_SIZE) { 2042b3230c8bSSteven Rostedt /* 2043b3230c8bSSteven Rostedt * If the page was filled, then we still need 2044b3230c8bSSteven Rostedt * to update the real_end. Reset it to zero 2045b3230c8bSSteven Rostedt * and the reader will ignore it. 2046b3230c8bSSteven Rostedt */ 2047b3230c8bSSteven Rostedt if (tail == BUF_PAGE_SIZE) 2048b3230c8bSSteven Rostedt tail_page->real_end = 0; 2049b3230c8bSSteven Rostedt 2050c7b09308SSteven Rostedt local_sub(length, &tail_page->write); 2051c7b09308SSteven Rostedt return; 2052c7b09308SSteven Rostedt } 2053c7b09308SSteven Rostedt 2054c7b09308SSteven Rostedt event = __rb_page_index(tail_page, tail); 2055c7b09308SSteven Rostedt 2056c64e148aSVaibhav Nagarnaik /* account for padding bytes */ 2057c64e148aSVaibhav Nagarnaik local_add(BUF_PAGE_SIZE - tail, &cpu_buffer->entries_bytes); 2058c64e148aSVaibhav Nagarnaik 2059c7b09308SSteven Rostedt /* 2060ff0ff84aSSteven Rostedt * Save the original length to the meta data. 2061ff0ff84aSSteven Rostedt * This will be used by the reader to add lost event 2062ff0ff84aSSteven Rostedt * counter. 2063ff0ff84aSSteven Rostedt */ 2064ff0ff84aSSteven Rostedt tail_page->real_end = tail; 2065ff0ff84aSSteven Rostedt 2066ff0ff84aSSteven Rostedt /* 2067c7b09308SSteven Rostedt * If this event is bigger than the minimum size, then 2068c7b09308SSteven Rostedt * we need to be careful that we don't subtract the 2069c7b09308SSteven Rostedt * write counter enough to allow another writer to slip 2070c7b09308SSteven Rostedt * in on this page. 2071c7b09308SSteven Rostedt * We put in a discarded commit instead, to make sure 2072c7b09308SSteven Rostedt * that this space is not used again. 2073c7b09308SSteven Rostedt * 2074c7b09308SSteven Rostedt * If we are less than the minimum size, we don't need to 2075c7b09308SSteven Rostedt * worry about it. 2076c7b09308SSteven Rostedt */ 2077c7b09308SSteven Rostedt if (tail > (BUF_PAGE_SIZE - RB_EVNT_MIN_SIZE)) { 2078c7b09308SSteven Rostedt /* No room for any events */ 2079c7b09308SSteven Rostedt 2080c7b09308SSteven Rostedt /* Mark the rest of the page with padding */ 2081c7b09308SSteven Rostedt rb_event_set_padding(event); 2082c7b09308SSteven Rostedt 2083c7b09308SSteven Rostedt /* Set the write back to the previous setting */ 2084c7b09308SSteven Rostedt local_sub(length, &tail_page->write); 2085c7b09308SSteven Rostedt return; 2086c7b09308SSteven Rostedt } 2087c7b09308SSteven Rostedt 2088c7b09308SSteven Rostedt /* Put in a discarded event */ 2089c7b09308SSteven Rostedt event->array[0] = (BUF_PAGE_SIZE - tail) - RB_EVNT_HDR_SIZE; 2090c7b09308SSteven Rostedt event->type_len = RINGBUF_TYPE_PADDING; 2091c7b09308SSteven Rostedt /* time delta must be non zero */ 2092c7b09308SSteven Rostedt event->time_delta = 1; 2093c7b09308SSteven Rostedt 2094c7b09308SSteven Rostedt /* Set write to end of buffer */ 2095c7b09308SSteven Rostedt length = (tail + length) - BUF_PAGE_SIZE; 2096c7b09308SSteven Rostedt local_sub(length, &tail_page->write); 2097c7b09308SSteven Rostedt } 20986634ff26SSteven Rostedt 20994239c38fSSteven Rostedt (Red Hat) static inline void rb_end_commit(struct ring_buffer_per_cpu *cpu_buffer); 21004239c38fSSteven Rostedt (Red Hat) 2101747e94aeSSteven Rostedt /* 2102747e94aeSSteven Rostedt * This is the slow path, force gcc not to inline it. 2103747e94aeSSteven Rostedt */ 2104747e94aeSSteven Rostedt static noinline struct ring_buffer_event * 21056634ff26SSteven Rostedt rb_move_tail(struct ring_buffer_per_cpu *cpu_buffer, 2106fcc742eaSSteven Rostedt (Red Hat) unsigned long tail, struct rb_event_info *info) 21077a8e76a3SSteven Rostedt { 2108fcc742eaSSteven Rostedt (Red Hat) struct buffer_page *tail_page = info->tail_page; 21095a50e33cSSteven Rostedt struct buffer_page *commit_page = cpu_buffer->commit_page; 21107a8e76a3SSteven Rostedt struct ring_buffer *buffer = cpu_buffer->buffer; 211177ae365eSSteven Rostedt struct buffer_page *next_page; 211277ae365eSSteven Rostedt int ret; 2113aa20ae84SSteven Rostedt 2114aa20ae84SSteven Rostedt next_page = tail_page; 21157a8e76a3SSteven Rostedt 21167a8e76a3SSteven Rostedt rb_inc_page(cpu_buffer, &next_page); 21177a8e76a3SSteven Rostedt 2118bf41a158SSteven Rostedt /* 2119bf41a158SSteven Rostedt * If for some reason, we had an interrupt storm that made 2120bf41a158SSteven Rostedt * it all the way around the buffer, bail, and warn 2121bf41a158SSteven Rostedt * about it. 2122bf41a158SSteven Rostedt */ 212398db8df7SSteven Rostedt if (unlikely(next_page == commit_page)) { 212477ae365eSSteven Rostedt local_inc(&cpu_buffer->commit_overrun); 212545141d46SSteven Rostedt goto out_reset; 2126bf41a158SSteven Rostedt } 2127d769041fSSteven Rostedt 2128bf41a158SSteven Rostedt /* 212977ae365eSSteven Rostedt * This is where the fun begins! 213077ae365eSSteven Rostedt * 213177ae365eSSteven Rostedt * We are fighting against races between a reader that 213277ae365eSSteven Rostedt * could be on another CPU trying to swap its reader 213377ae365eSSteven Rostedt * page with the buffer head. 213477ae365eSSteven Rostedt * 213577ae365eSSteven Rostedt * We are also fighting against interrupts coming in and 213677ae365eSSteven Rostedt * moving the head or tail on us as well. 213777ae365eSSteven Rostedt * 213877ae365eSSteven Rostedt * If the next page is the head page then we have filled 213977ae365eSSteven Rostedt * the buffer, unless the commit page is still on the 214077ae365eSSteven Rostedt * reader page. 2141bf41a158SSteven Rostedt */ 214277ae365eSSteven Rostedt if (rb_is_head_page(cpu_buffer, next_page, &tail_page->list)) { 2143bf41a158SSteven Rostedt 214477ae365eSSteven Rostedt /* 214577ae365eSSteven Rostedt * If the commit is not on the reader page, then 214677ae365eSSteven Rostedt * move the header page. 214777ae365eSSteven Rostedt */ 214877ae365eSSteven Rostedt if (!rb_is_reader_page(cpu_buffer->commit_page)) { 214977ae365eSSteven Rostedt /* 215077ae365eSSteven Rostedt * If we are not in overwrite mode, 215177ae365eSSteven Rostedt * this is easy, just stop here. 215277ae365eSSteven Rostedt */ 2153884bfe89SSlava Pestov if (!(buffer->flags & RB_FL_OVERWRITE)) { 2154884bfe89SSlava Pestov local_inc(&cpu_buffer->dropped_events); 215577ae365eSSteven Rostedt goto out_reset; 2156884bfe89SSlava Pestov } 215777ae365eSSteven Rostedt 215877ae365eSSteven Rostedt ret = rb_handle_head_page(cpu_buffer, 215977ae365eSSteven Rostedt tail_page, 216077ae365eSSteven Rostedt next_page); 216177ae365eSSteven Rostedt if (ret < 0) 216277ae365eSSteven Rostedt goto out_reset; 216377ae365eSSteven Rostedt if (ret) 216477ae365eSSteven Rostedt goto out_again; 216577ae365eSSteven Rostedt } else { 216677ae365eSSteven Rostedt /* 216777ae365eSSteven Rostedt * We need to be careful here too. The 216877ae365eSSteven Rostedt * commit page could still be on the reader 216977ae365eSSteven Rostedt * page. We could have a small buffer, and 217077ae365eSSteven Rostedt * have filled up the buffer with events 217177ae365eSSteven Rostedt * from interrupts and such, and wrapped. 217277ae365eSSteven Rostedt * 217377ae365eSSteven Rostedt * Note, if the tail page is also the on the 217477ae365eSSteven Rostedt * reader_page, we let it move out. 217577ae365eSSteven Rostedt */ 217677ae365eSSteven Rostedt if (unlikely((cpu_buffer->commit_page != 217777ae365eSSteven Rostedt cpu_buffer->tail_page) && 217877ae365eSSteven Rostedt (cpu_buffer->commit_page == 217977ae365eSSteven Rostedt cpu_buffer->reader_page))) { 218077ae365eSSteven Rostedt local_inc(&cpu_buffer->commit_overrun); 218177ae365eSSteven Rostedt goto out_reset; 218277ae365eSSteven Rostedt } 218377ae365eSSteven Rostedt } 2184bf41a158SSteven Rostedt } 2185bf41a158SSteven Rostedt 218670004986SSteven Rostedt (Red Hat) rb_tail_page_update(cpu_buffer, tail_page, next_page); 21877a8e76a3SSteven Rostedt 218877ae365eSSteven Rostedt out_again: 218977ae365eSSteven Rostedt 2190fcc742eaSSteven Rostedt (Red Hat) rb_reset_tail(cpu_buffer, tail, info); 2191bf41a158SSteven Rostedt 21924239c38fSSteven Rostedt (Red Hat) /* Commit what we have for now. */ 21934239c38fSSteven Rostedt (Red Hat) rb_end_commit(cpu_buffer); 21944239c38fSSteven Rostedt (Red Hat) /* rb_end_commit() decs committing */ 21954239c38fSSteven Rostedt (Red Hat) local_inc(&cpu_buffer->committing); 21964239c38fSSteven Rostedt (Red Hat) 2197bf41a158SSteven Rostedt /* fail and let the caller try again */ 2198bf41a158SSteven Rostedt return ERR_PTR(-EAGAIN); 2199bf41a158SSteven Rostedt 220045141d46SSteven Rostedt out_reset: 22016f3b3440SLai Jiangshan /* reset write */ 2202fcc742eaSSteven Rostedt (Red Hat) rb_reset_tail(cpu_buffer, tail, info); 22036f3b3440SLai Jiangshan 2204bf41a158SSteven Rostedt return NULL; 22057a8e76a3SSteven Rostedt } 22067a8e76a3SSteven Rostedt 2207d90fd774SSteven Rostedt (Red Hat) /* Slow path, do not inline */ 2208d90fd774SSteven Rostedt (Red Hat) static noinline struct ring_buffer_event * 2209d90fd774SSteven Rostedt (Red Hat) rb_add_time_stamp(struct ring_buffer_event *event, u64 delta) 2210d90fd774SSteven Rostedt (Red Hat) { 2211d90fd774SSteven Rostedt (Red Hat) event->type_len = RINGBUF_TYPE_TIME_EXTEND; 2212d90fd774SSteven Rostedt (Red Hat) 2213d90fd774SSteven Rostedt (Red Hat) /* Not the first event on the page? */ 2214d90fd774SSteven Rostedt (Red Hat) if (rb_event_index(event)) { 2215d90fd774SSteven Rostedt (Red Hat) event->time_delta = delta & TS_MASK; 2216d90fd774SSteven Rostedt (Red Hat) event->array[0] = delta >> TS_SHIFT; 2217d90fd774SSteven Rostedt (Red Hat) } else { 2218d90fd774SSteven Rostedt (Red Hat) /* nope, just zero it */ 2219d90fd774SSteven Rostedt (Red Hat) event->time_delta = 0; 2220d90fd774SSteven Rostedt (Red Hat) event->array[0] = 0; 2221d90fd774SSteven Rostedt (Red Hat) } 2222d90fd774SSteven Rostedt (Red Hat) 2223d90fd774SSteven Rostedt (Red Hat) return skip_time_extend(event); 2224d90fd774SSteven Rostedt (Red Hat) } 2225d90fd774SSteven Rostedt (Red Hat) 2226cdb2a0a9SYaowei Bai static inline bool rb_event_is_commit(struct ring_buffer_per_cpu *cpu_buffer, 2227b7dc42fdSSteven Rostedt (Red Hat) struct ring_buffer_event *event); 2228b7dc42fdSSteven Rostedt (Red Hat) 2229d90fd774SSteven Rostedt (Red Hat) /** 2230d90fd774SSteven Rostedt (Red Hat) * rb_update_event - update event type and data 2231d90fd774SSteven Rostedt (Red Hat) * @event: the event to update 2232d90fd774SSteven Rostedt (Red Hat) * @type: the type of event 2233d90fd774SSteven Rostedt (Red Hat) * @length: the size of the event field in the ring buffer 2234d90fd774SSteven Rostedt (Red Hat) * 2235d90fd774SSteven Rostedt (Red Hat) * Update the type and data fields of the event. The length 2236d90fd774SSteven Rostedt (Red Hat) * is the actual size that is written to the ring buffer, 2237d90fd774SSteven Rostedt (Red Hat) * and with this, we can determine what to place into the 2238d90fd774SSteven Rostedt (Red Hat) * data field. 2239d90fd774SSteven Rostedt (Red Hat) */ 2240b7dc42fdSSteven Rostedt (Red Hat) static void 2241d90fd774SSteven Rostedt (Red Hat) rb_update_event(struct ring_buffer_per_cpu *cpu_buffer, 2242d90fd774SSteven Rostedt (Red Hat) struct ring_buffer_event *event, 2243d90fd774SSteven Rostedt (Red Hat) struct rb_event_info *info) 2244d90fd774SSteven Rostedt (Red Hat) { 2245d90fd774SSteven Rostedt (Red Hat) unsigned length = info->length; 2246d90fd774SSteven Rostedt (Red Hat) u64 delta = info->delta; 2247d90fd774SSteven Rostedt (Red Hat) 2248b7dc42fdSSteven Rostedt (Red Hat) /* Only a commit updates the timestamp */ 2249b7dc42fdSSteven Rostedt (Red Hat) if (unlikely(!rb_event_is_commit(cpu_buffer, event))) 2250b7dc42fdSSteven Rostedt (Red Hat) delta = 0; 2251b7dc42fdSSteven Rostedt (Red Hat) 2252d90fd774SSteven Rostedt (Red Hat) /* 2253d90fd774SSteven Rostedt (Red Hat) * If we need to add a timestamp, then we 2254d90fd774SSteven Rostedt (Red Hat) * add it to the start of the resevered space. 2255d90fd774SSteven Rostedt (Red Hat) */ 2256d90fd774SSteven Rostedt (Red Hat) if (unlikely(info->add_timestamp)) { 2257d90fd774SSteven Rostedt (Red Hat) event = rb_add_time_stamp(event, delta); 2258d90fd774SSteven Rostedt (Red Hat) length -= RB_LEN_TIME_EXTEND; 2259d90fd774SSteven Rostedt (Red Hat) delta = 0; 2260d90fd774SSteven Rostedt (Red Hat) } 2261d90fd774SSteven Rostedt (Red Hat) 2262d90fd774SSteven Rostedt (Red Hat) event->time_delta = delta; 2263d90fd774SSteven Rostedt (Red Hat) length -= RB_EVNT_HDR_SIZE; 2264d90fd774SSteven Rostedt (Red Hat) if (length > RB_MAX_SMALL_DATA || RB_FORCE_8BYTE_ALIGNMENT) { 2265d90fd774SSteven Rostedt (Red Hat) event->type_len = 0; 2266d90fd774SSteven Rostedt (Red Hat) event->array[0] = length; 2267d90fd774SSteven Rostedt (Red Hat) } else 2268d90fd774SSteven Rostedt (Red Hat) event->type_len = DIV_ROUND_UP(length, RB_ALIGNMENT); 2269d90fd774SSteven Rostedt (Red Hat) } 2270d90fd774SSteven Rostedt (Red Hat) 2271d90fd774SSteven Rostedt (Red Hat) static unsigned rb_calculate_event_length(unsigned length) 2272d90fd774SSteven Rostedt (Red Hat) { 2273d90fd774SSteven Rostedt (Red Hat) struct ring_buffer_event event; /* Used only for sizeof array */ 2274d90fd774SSteven Rostedt (Red Hat) 2275d90fd774SSteven Rostedt (Red Hat) /* zero length can cause confusions */ 2276d90fd774SSteven Rostedt (Red Hat) if (!length) 2277d90fd774SSteven Rostedt (Red Hat) length++; 2278d90fd774SSteven Rostedt (Red Hat) 2279d90fd774SSteven Rostedt (Red Hat) if (length > RB_MAX_SMALL_DATA || RB_FORCE_8BYTE_ALIGNMENT) 2280d90fd774SSteven Rostedt (Red Hat) length += sizeof(event.array[0]); 2281d90fd774SSteven Rostedt (Red Hat) 2282d90fd774SSteven Rostedt (Red Hat) length += RB_EVNT_HDR_SIZE; 2283d90fd774SSteven Rostedt (Red Hat) length = ALIGN(length, RB_ARCH_ALIGNMENT); 2284d90fd774SSteven Rostedt (Red Hat) 2285d90fd774SSteven Rostedt (Red Hat) /* 2286d90fd774SSteven Rostedt (Red Hat) * In case the time delta is larger than the 27 bits for it 2287d90fd774SSteven Rostedt (Red Hat) * in the header, we need to add a timestamp. If another 2288d90fd774SSteven Rostedt (Red Hat) * event comes in when trying to discard this one to increase 2289d90fd774SSteven Rostedt (Red Hat) * the length, then the timestamp will be added in the allocated 2290d90fd774SSteven Rostedt (Red Hat) * space of this event. If length is bigger than the size needed 2291d90fd774SSteven Rostedt (Red Hat) * for the TIME_EXTEND, then padding has to be used. The events 2292d90fd774SSteven Rostedt (Red Hat) * length must be either RB_LEN_TIME_EXTEND, or greater than or equal 2293d90fd774SSteven Rostedt (Red Hat) * to RB_LEN_TIME_EXTEND + 8, as 8 is the minimum size for padding. 2294d90fd774SSteven Rostedt (Red Hat) * As length is a multiple of 4, we only need to worry if it 2295d90fd774SSteven Rostedt (Red Hat) * is 12 (RB_LEN_TIME_EXTEND + 4). 2296d90fd774SSteven Rostedt (Red Hat) */ 2297d90fd774SSteven Rostedt (Red Hat) if (length == RB_LEN_TIME_EXTEND + RB_ALIGNMENT) 2298d90fd774SSteven Rostedt (Red Hat) length += RB_ALIGNMENT; 2299d90fd774SSteven Rostedt (Red Hat) 2300d90fd774SSteven Rostedt (Red Hat) return length; 2301d90fd774SSteven Rostedt (Red Hat) } 2302d90fd774SSteven Rostedt (Red Hat) 23039826b273SSteven Rostedt (Red Hat) #ifndef CONFIG_HAVE_UNSTABLE_SCHED_CLOCK 23049826b273SSteven Rostedt (Red Hat) static inline bool sched_clock_stable(void) 23059826b273SSteven Rostedt (Red Hat) { 23069826b273SSteven Rostedt (Red Hat) return true; 23079826b273SSteven Rostedt (Red Hat) } 23089826b273SSteven Rostedt (Red Hat) #endif 23099826b273SSteven Rostedt (Red Hat) 2310a4543a2fSSteven Rostedt (Red Hat) static inline int 2311a4543a2fSSteven Rostedt (Red Hat) rb_try_to_discard(struct ring_buffer_per_cpu *cpu_buffer, 2312d90fd774SSteven Rostedt (Red Hat) struct ring_buffer_event *event) 2313d90fd774SSteven Rostedt (Red Hat) { 2314d90fd774SSteven Rostedt (Red Hat) unsigned long new_index, old_index; 2315d90fd774SSteven Rostedt (Red Hat) struct buffer_page *bpage; 2316d90fd774SSteven Rostedt (Red Hat) unsigned long index; 2317d90fd774SSteven Rostedt (Red Hat) unsigned long addr; 2318d90fd774SSteven Rostedt (Red Hat) 2319d90fd774SSteven Rostedt (Red Hat) new_index = rb_event_index(event); 2320d90fd774SSteven Rostedt (Red Hat) old_index = new_index + rb_event_ts_length(event); 2321d90fd774SSteven Rostedt (Red Hat) addr = (unsigned long)event; 2322d90fd774SSteven Rostedt (Red Hat) addr &= PAGE_MASK; 2323d90fd774SSteven Rostedt (Red Hat) 23248573636eSSteven Rostedt (Red Hat) bpage = READ_ONCE(cpu_buffer->tail_page); 2325d90fd774SSteven Rostedt (Red Hat) 2326d90fd774SSteven Rostedt (Red Hat) if (bpage->page == (void *)addr && rb_page_write(bpage) == old_index) { 2327d90fd774SSteven Rostedt (Red Hat) unsigned long write_mask = 2328d90fd774SSteven Rostedt (Red Hat) local_read(&bpage->write) & ~RB_WRITE_MASK; 2329d90fd774SSteven Rostedt (Red Hat) unsigned long event_length = rb_event_length(event); 2330d90fd774SSteven Rostedt (Red Hat) /* 2331d90fd774SSteven Rostedt (Red Hat) * This is on the tail page. It is possible that 2332d90fd774SSteven Rostedt (Red Hat) * a write could come in and move the tail page 2333d90fd774SSteven Rostedt (Red Hat) * and write to the next page. That is fine 2334d90fd774SSteven Rostedt (Red Hat) * because we just shorten what is on this page. 2335d90fd774SSteven Rostedt (Red Hat) */ 2336d90fd774SSteven Rostedt (Red Hat) old_index += write_mask; 2337d90fd774SSteven Rostedt (Red Hat) new_index += write_mask; 2338d90fd774SSteven Rostedt (Red Hat) index = local_cmpxchg(&bpage->write, old_index, new_index); 2339d90fd774SSteven Rostedt (Red Hat) if (index == old_index) { 2340d90fd774SSteven Rostedt (Red Hat) /* update counters */ 2341d90fd774SSteven Rostedt (Red Hat) local_sub(event_length, &cpu_buffer->entries_bytes); 2342d90fd774SSteven Rostedt (Red Hat) return 1; 2343d90fd774SSteven Rostedt (Red Hat) } 2344d90fd774SSteven Rostedt (Red Hat) } 2345d90fd774SSteven Rostedt (Red Hat) 2346d90fd774SSteven Rostedt (Red Hat) /* could not discard */ 2347d90fd774SSteven Rostedt (Red Hat) return 0; 2348d90fd774SSteven Rostedt (Red Hat) } 2349d90fd774SSteven Rostedt (Red Hat) 2350d90fd774SSteven Rostedt (Red Hat) static void rb_start_commit(struct ring_buffer_per_cpu *cpu_buffer) 2351d90fd774SSteven Rostedt (Red Hat) { 2352d90fd774SSteven Rostedt (Red Hat) local_inc(&cpu_buffer->committing); 2353d90fd774SSteven Rostedt (Red Hat) local_inc(&cpu_buffer->commits); 2354d90fd774SSteven Rostedt (Red Hat) } 2355d90fd774SSteven Rostedt (Red Hat) 235638e11df1SSteven Rostedt (Red Hat) static __always_inline void 2357d90fd774SSteven Rostedt (Red Hat) rb_set_commit_to_write(struct ring_buffer_per_cpu *cpu_buffer) 2358d90fd774SSteven Rostedt (Red Hat) { 2359d90fd774SSteven Rostedt (Red Hat) unsigned long max_count; 2360d90fd774SSteven Rostedt (Red Hat) 2361d90fd774SSteven Rostedt (Red Hat) /* 2362d90fd774SSteven Rostedt (Red Hat) * We only race with interrupts and NMIs on this CPU. 2363d90fd774SSteven Rostedt (Red Hat) * If we own the commit event, then we can commit 2364d90fd774SSteven Rostedt (Red Hat) * all others that interrupted us, since the interruptions 2365d90fd774SSteven Rostedt (Red Hat) * are in stack format (they finish before they come 2366d90fd774SSteven Rostedt (Red Hat) * back to us). This allows us to do a simple loop to 2367d90fd774SSteven Rostedt (Red Hat) * assign the commit to the tail. 2368d90fd774SSteven Rostedt (Red Hat) */ 2369d90fd774SSteven Rostedt (Red Hat) again: 2370d90fd774SSteven Rostedt (Red Hat) max_count = cpu_buffer->nr_pages * 100; 2371d90fd774SSteven Rostedt (Red Hat) 23728573636eSSteven Rostedt (Red Hat) while (cpu_buffer->commit_page != READ_ONCE(cpu_buffer->tail_page)) { 2373d90fd774SSteven Rostedt (Red Hat) if (RB_WARN_ON(cpu_buffer, !(--max_count))) 2374d90fd774SSteven Rostedt (Red Hat) return; 2375d90fd774SSteven Rostedt (Red Hat) if (RB_WARN_ON(cpu_buffer, 2376d90fd774SSteven Rostedt (Red Hat) rb_is_reader_page(cpu_buffer->tail_page))) 2377d90fd774SSteven Rostedt (Red Hat) return; 2378d90fd774SSteven Rostedt (Red Hat) local_set(&cpu_buffer->commit_page->page->commit, 2379d90fd774SSteven Rostedt (Red Hat) rb_page_write(cpu_buffer->commit_page)); 2380d90fd774SSteven Rostedt (Red Hat) rb_inc_page(cpu_buffer, &cpu_buffer->commit_page); 238170004986SSteven Rostedt (Red Hat) /* Only update the write stamp if the page has an event */ 238270004986SSteven Rostedt (Red Hat) if (rb_page_write(cpu_buffer->commit_page)) 2383d90fd774SSteven Rostedt (Red Hat) cpu_buffer->write_stamp = 2384d90fd774SSteven Rostedt (Red Hat) cpu_buffer->commit_page->page->time_stamp; 2385d90fd774SSteven Rostedt (Red Hat) /* add barrier to keep gcc from optimizing too much */ 2386d90fd774SSteven Rostedt (Red Hat) barrier(); 2387d90fd774SSteven Rostedt (Red Hat) } 2388d90fd774SSteven Rostedt (Red Hat) while (rb_commit_index(cpu_buffer) != 2389d90fd774SSteven Rostedt (Red Hat) rb_page_write(cpu_buffer->commit_page)) { 2390d90fd774SSteven Rostedt (Red Hat) 2391d90fd774SSteven Rostedt (Red Hat) local_set(&cpu_buffer->commit_page->page->commit, 2392d90fd774SSteven Rostedt (Red Hat) rb_page_write(cpu_buffer->commit_page)); 2393d90fd774SSteven Rostedt (Red Hat) RB_WARN_ON(cpu_buffer, 2394d90fd774SSteven Rostedt (Red Hat) local_read(&cpu_buffer->commit_page->page->commit) & 2395d90fd774SSteven Rostedt (Red Hat) ~RB_WRITE_MASK); 2396d90fd774SSteven Rostedt (Red Hat) barrier(); 2397d90fd774SSteven Rostedt (Red Hat) } 2398d90fd774SSteven Rostedt (Red Hat) 2399d90fd774SSteven Rostedt (Red Hat) /* again, keep gcc from optimizing */ 2400d90fd774SSteven Rostedt (Red Hat) barrier(); 2401d90fd774SSteven Rostedt (Red Hat) 2402d90fd774SSteven Rostedt (Red Hat) /* 2403d90fd774SSteven Rostedt (Red Hat) * If an interrupt came in just after the first while loop 2404d90fd774SSteven Rostedt (Red Hat) * and pushed the tail page forward, we will be left with 2405d90fd774SSteven Rostedt (Red Hat) * a dangling commit that will never go forward. 2406d90fd774SSteven Rostedt (Red Hat) */ 24078573636eSSteven Rostedt (Red Hat) if (unlikely(cpu_buffer->commit_page != READ_ONCE(cpu_buffer->tail_page))) 2408d90fd774SSteven Rostedt (Red Hat) goto again; 2409d90fd774SSteven Rostedt (Red Hat) } 2410d90fd774SSteven Rostedt (Red Hat) 241138e11df1SSteven Rostedt (Red Hat) static __always_inline void rb_end_commit(struct ring_buffer_per_cpu *cpu_buffer) 2412d90fd774SSteven Rostedt (Red Hat) { 2413d90fd774SSteven Rostedt (Red Hat) unsigned long commits; 2414d90fd774SSteven Rostedt (Red Hat) 2415d90fd774SSteven Rostedt (Red Hat) if (RB_WARN_ON(cpu_buffer, 2416d90fd774SSteven Rostedt (Red Hat) !local_read(&cpu_buffer->committing))) 2417d90fd774SSteven Rostedt (Red Hat) return; 2418d90fd774SSteven Rostedt (Red Hat) 2419d90fd774SSteven Rostedt (Red Hat) again: 2420d90fd774SSteven Rostedt (Red Hat) commits = local_read(&cpu_buffer->commits); 2421d90fd774SSteven Rostedt (Red Hat) /* synchronize with interrupts */ 2422d90fd774SSteven Rostedt (Red Hat) barrier(); 2423d90fd774SSteven Rostedt (Red Hat) if (local_read(&cpu_buffer->committing) == 1) 2424d90fd774SSteven Rostedt (Red Hat) rb_set_commit_to_write(cpu_buffer); 2425d90fd774SSteven Rostedt (Red Hat) 2426d90fd774SSteven Rostedt (Red Hat) local_dec(&cpu_buffer->committing); 2427d90fd774SSteven Rostedt (Red Hat) 2428d90fd774SSteven Rostedt (Red Hat) /* synchronize with interrupts */ 2429d90fd774SSteven Rostedt (Red Hat) barrier(); 2430d90fd774SSteven Rostedt (Red Hat) 2431d90fd774SSteven Rostedt (Red Hat) /* 2432d90fd774SSteven Rostedt (Red Hat) * Need to account for interrupts coming in between the 2433d90fd774SSteven Rostedt (Red Hat) * updating of the commit page and the clearing of the 2434d90fd774SSteven Rostedt (Red Hat) * committing counter. 2435d90fd774SSteven Rostedt (Red Hat) */ 2436d90fd774SSteven Rostedt (Red Hat) if (unlikely(local_read(&cpu_buffer->commits) != commits) && 2437d90fd774SSteven Rostedt (Red Hat) !local_read(&cpu_buffer->committing)) { 2438d90fd774SSteven Rostedt (Red Hat) local_inc(&cpu_buffer->committing); 2439d90fd774SSteven Rostedt (Red Hat) goto again; 2440d90fd774SSteven Rostedt (Red Hat) } 2441d90fd774SSteven Rostedt (Red Hat) } 2442d90fd774SSteven Rostedt (Red Hat) 2443d90fd774SSteven Rostedt (Red Hat) static inline void rb_event_discard(struct ring_buffer_event *event) 2444d90fd774SSteven Rostedt (Red Hat) { 2445d90fd774SSteven Rostedt (Red Hat) if (event->type_len == RINGBUF_TYPE_TIME_EXTEND) 2446d90fd774SSteven Rostedt (Red Hat) event = skip_time_extend(event); 2447d90fd774SSteven Rostedt (Red Hat) 2448d90fd774SSteven Rostedt (Red Hat) /* array[0] holds the actual length for the discarded event */ 2449d90fd774SSteven Rostedt (Red Hat) event->array[0] = rb_event_data_length(event) - RB_EVNT_HDR_SIZE; 2450d90fd774SSteven Rostedt (Red Hat) event->type_len = RINGBUF_TYPE_PADDING; 2451d90fd774SSteven Rostedt (Red Hat) /* time delta must be non zero */ 2452d90fd774SSteven Rostedt (Red Hat) if (!event->time_delta) 2453d90fd774SSteven Rostedt (Red Hat) event->time_delta = 1; 2454d90fd774SSteven Rostedt (Red Hat) } 2455d90fd774SSteven Rostedt (Red Hat) 2456babe3fceSSteven Rostedt (Red Hat) static __always_inline bool 2457d90fd774SSteven Rostedt (Red Hat) rb_event_is_commit(struct ring_buffer_per_cpu *cpu_buffer, 2458d90fd774SSteven Rostedt (Red Hat) struct ring_buffer_event *event) 2459d90fd774SSteven Rostedt (Red Hat) { 2460d90fd774SSteven Rostedt (Red Hat) unsigned long addr = (unsigned long)event; 2461d90fd774SSteven Rostedt (Red Hat) unsigned long index; 2462d90fd774SSteven Rostedt (Red Hat) 2463d90fd774SSteven Rostedt (Red Hat) index = rb_event_index(event); 2464d90fd774SSteven Rostedt (Red Hat) addr &= PAGE_MASK; 2465d90fd774SSteven Rostedt (Red Hat) 2466d90fd774SSteven Rostedt (Red Hat) return cpu_buffer->commit_page->page == (void *)addr && 2467d90fd774SSteven Rostedt (Red Hat) rb_commit_index(cpu_buffer) == index; 2468d90fd774SSteven Rostedt (Red Hat) } 2469d90fd774SSteven Rostedt (Red Hat) 2470babe3fceSSteven Rostedt (Red Hat) static __always_inline void 2471a4543a2fSSteven Rostedt (Red Hat) rb_update_write_stamp(struct ring_buffer_per_cpu *cpu_buffer, 2472d90fd774SSteven Rostedt (Red Hat) struct ring_buffer_event *event) 2473d90fd774SSteven Rostedt (Red Hat) { 2474d90fd774SSteven Rostedt (Red Hat) u64 delta; 2475d90fd774SSteven Rostedt (Red Hat) 2476d90fd774SSteven Rostedt (Red Hat) /* 2477d90fd774SSteven Rostedt (Red Hat) * The event first in the commit queue updates the 2478d90fd774SSteven Rostedt (Red Hat) * time stamp. 2479d90fd774SSteven Rostedt (Red Hat) */ 2480d90fd774SSteven Rostedt (Red Hat) if (rb_event_is_commit(cpu_buffer, event)) { 2481d90fd774SSteven Rostedt (Red Hat) /* 2482d90fd774SSteven Rostedt (Red Hat) * A commit event that is first on a page 2483d90fd774SSteven Rostedt (Red Hat) * updates the write timestamp with the page stamp 2484d90fd774SSteven Rostedt (Red Hat) */ 2485d90fd774SSteven Rostedt (Red Hat) if (!rb_event_index(event)) 2486d90fd774SSteven Rostedt (Red Hat) cpu_buffer->write_stamp = 2487d90fd774SSteven Rostedt (Red Hat) cpu_buffer->commit_page->page->time_stamp; 2488d90fd774SSteven Rostedt (Red Hat) else if (event->type_len == RINGBUF_TYPE_TIME_EXTEND) { 2489d90fd774SSteven Rostedt (Red Hat) delta = event->array[0]; 2490d90fd774SSteven Rostedt (Red Hat) delta <<= TS_SHIFT; 2491d90fd774SSteven Rostedt (Red Hat) delta += event->time_delta; 2492d90fd774SSteven Rostedt (Red Hat) cpu_buffer->write_stamp += delta; 2493d90fd774SSteven Rostedt (Red Hat) } else 2494d90fd774SSteven Rostedt (Red Hat) cpu_buffer->write_stamp += event->time_delta; 2495d90fd774SSteven Rostedt (Red Hat) } 2496d90fd774SSteven Rostedt (Red Hat) } 2497d90fd774SSteven Rostedt (Red Hat) 2498d90fd774SSteven Rostedt (Red Hat) static void rb_commit(struct ring_buffer_per_cpu *cpu_buffer, 2499d90fd774SSteven Rostedt (Red Hat) struct ring_buffer_event *event) 2500d90fd774SSteven Rostedt (Red Hat) { 2501d90fd774SSteven Rostedt (Red Hat) local_inc(&cpu_buffer->entries); 2502d90fd774SSteven Rostedt (Red Hat) rb_update_write_stamp(cpu_buffer, event); 2503d90fd774SSteven Rostedt (Red Hat) rb_end_commit(cpu_buffer); 2504d90fd774SSteven Rostedt (Red Hat) } 2505d90fd774SSteven Rostedt (Red Hat) 2506d90fd774SSteven Rostedt (Red Hat) static __always_inline void 2507d90fd774SSteven Rostedt (Red Hat) rb_wakeups(struct ring_buffer *buffer, struct ring_buffer_per_cpu *cpu_buffer) 2508d90fd774SSteven Rostedt (Red Hat) { 2509d90fd774SSteven Rostedt (Red Hat) bool pagebusy; 2510d90fd774SSteven Rostedt (Red Hat) 2511d90fd774SSteven Rostedt (Red Hat) if (buffer->irq_work.waiters_pending) { 2512d90fd774SSteven Rostedt (Red Hat) buffer->irq_work.waiters_pending = false; 2513d90fd774SSteven Rostedt (Red Hat) /* irq_work_queue() supplies it's own memory barriers */ 2514d90fd774SSteven Rostedt (Red Hat) irq_work_queue(&buffer->irq_work.work); 2515d90fd774SSteven Rostedt (Red Hat) } 2516d90fd774SSteven Rostedt (Red Hat) 2517d90fd774SSteven Rostedt (Red Hat) if (cpu_buffer->irq_work.waiters_pending) { 2518d90fd774SSteven Rostedt (Red Hat) cpu_buffer->irq_work.waiters_pending = false; 2519d90fd774SSteven Rostedt (Red Hat) /* irq_work_queue() supplies it's own memory barriers */ 2520d90fd774SSteven Rostedt (Red Hat) irq_work_queue(&cpu_buffer->irq_work.work); 2521d90fd774SSteven Rostedt (Red Hat) } 2522d90fd774SSteven Rostedt (Red Hat) 2523d90fd774SSteven Rostedt (Red Hat) pagebusy = cpu_buffer->reader_page == cpu_buffer->commit_page; 2524d90fd774SSteven Rostedt (Red Hat) 2525d90fd774SSteven Rostedt (Red Hat) if (!pagebusy && cpu_buffer->irq_work.full_waiters_pending) { 2526d90fd774SSteven Rostedt (Red Hat) cpu_buffer->irq_work.wakeup_full = true; 2527d90fd774SSteven Rostedt (Red Hat) cpu_buffer->irq_work.full_waiters_pending = false; 2528d90fd774SSteven Rostedt (Red Hat) /* irq_work_queue() supplies it's own memory barriers */ 2529d90fd774SSteven Rostedt (Red Hat) irq_work_queue(&cpu_buffer->irq_work.work); 2530d90fd774SSteven Rostedt (Red Hat) } 2531d90fd774SSteven Rostedt (Red Hat) } 2532d90fd774SSteven Rostedt (Red Hat) 2533d90fd774SSteven Rostedt (Red Hat) /* 2534d90fd774SSteven Rostedt (Red Hat) * The lock and unlock are done within a preempt disable section. 2535d90fd774SSteven Rostedt (Red Hat) * The current_context per_cpu variable can only be modified 2536d90fd774SSteven Rostedt (Red Hat) * by the current task between lock and unlock. But it can 25371a149d7dSSteven Rostedt (VMware) * be modified more than once via an interrupt. There are four 25381a149d7dSSteven Rostedt (VMware) * different contexts that we need to consider. 2539d90fd774SSteven Rostedt (Red Hat) * 25401a149d7dSSteven Rostedt (VMware) * Normal context. 25411a149d7dSSteven Rostedt (VMware) * SoftIRQ context 25421a149d7dSSteven Rostedt (VMware) * IRQ context 25431a149d7dSSteven Rostedt (VMware) * NMI context 2544d90fd774SSteven Rostedt (Red Hat) * 25451a149d7dSSteven Rostedt (VMware) * If for some reason the ring buffer starts to recurse, we 25461a149d7dSSteven Rostedt (VMware) * only allow that to happen at most 4 times (one for each 25471a149d7dSSteven Rostedt (VMware) * context). If it happens 5 times, then we consider this a 25481a149d7dSSteven Rostedt (VMware) * recusive loop and do not let it go further. 2549d90fd774SSteven Rostedt (Red Hat) */ 2550d90fd774SSteven Rostedt (Red Hat) 2551d90fd774SSteven Rostedt (Red Hat) static __always_inline int 2552d90fd774SSteven Rostedt (Red Hat) trace_recursive_lock(struct ring_buffer_per_cpu *cpu_buffer) 2553d90fd774SSteven Rostedt (Red Hat) { 25541a149d7dSSteven Rostedt (VMware) if (cpu_buffer->current_context >= 4) 2555d90fd774SSteven Rostedt (Red Hat) return 1; 2556d90fd774SSteven Rostedt (Red Hat) 25571a149d7dSSteven Rostedt (VMware) cpu_buffer->current_context++; 25581a149d7dSSteven Rostedt (VMware) /* Interrupts must see this update */ 25591a149d7dSSteven Rostedt (VMware) barrier(); 2560d90fd774SSteven Rostedt (Red Hat) 2561d90fd774SSteven Rostedt (Red Hat) return 0; 2562d90fd774SSteven Rostedt (Red Hat) } 2563d90fd774SSteven Rostedt (Red Hat) 2564d90fd774SSteven Rostedt (Red Hat) static __always_inline void 2565d90fd774SSteven Rostedt (Red Hat) trace_recursive_unlock(struct ring_buffer_per_cpu *cpu_buffer) 2566d90fd774SSteven Rostedt (Red Hat) { 25671a149d7dSSteven Rostedt (VMware) /* Don't let the dec leak out */ 25681a149d7dSSteven Rostedt (VMware) barrier(); 25691a149d7dSSteven Rostedt (VMware) cpu_buffer->current_context--; 2570d90fd774SSteven Rostedt (Red Hat) } 2571d90fd774SSteven Rostedt (Red Hat) 2572d90fd774SSteven Rostedt (Red Hat) /** 2573d90fd774SSteven Rostedt (Red Hat) * ring_buffer_unlock_commit - commit a reserved 2574d90fd774SSteven Rostedt (Red Hat) * @buffer: The buffer to commit to 2575d90fd774SSteven Rostedt (Red Hat) * @event: The event pointer to commit. 2576d90fd774SSteven Rostedt (Red Hat) * 2577d90fd774SSteven Rostedt (Red Hat) * This commits the data to the ring buffer, and releases any locks held. 2578d90fd774SSteven Rostedt (Red Hat) * 2579d90fd774SSteven Rostedt (Red Hat) * Must be paired with ring_buffer_lock_reserve. 2580d90fd774SSteven Rostedt (Red Hat) */ 2581d90fd774SSteven Rostedt (Red Hat) int ring_buffer_unlock_commit(struct ring_buffer *buffer, 2582d90fd774SSteven Rostedt (Red Hat) struct ring_buffer_event *event) 2583d90fd774SSteven Rostedt (Red Hat) { 2584d90fd774SSteven Rostedt (Red Hat) struct ring_buffer_per_cpu *cpu_buffer; 2585d90fd774SSteven Rostedt (Red Hat) int cpu = raw_smp_processor_id(); 2586d90fd774SSteven Rostedt (Red Hat) 2587d90fd774SSteven Rostedt (Red Hat) cpu_buffer = buffer->buffers[cpu]; 2588d90fd774SSteven Rostedt (Red Hat) 2589d90fd774SSteven Rostedt (Red Hat) rb_commit(cpu_buffer, event); 2590d90fd774SSteven Rostedt (Red Hat) 2591d90fd774SSteven Rostedt (Red Hat) rb_wakeups(buffer, cpu_buffer); 2592d90fd774SSteven Rostedt (Red Hat) 2593d90fd774SSteven Rostedt (Red Hat) trace_recursive_unlock(cpu_buffer); 2594d90fd774SSteven Rostedt (Red Hat) 2595d90fd774SSteven Rostedt (Red Hat) preempt_enable_notrace(); 2596d90fd774SSteven Rostedt (Red Hat) 2597d90fd774SSteven Rostedt (Red Hat) return 0; 2598d90fd774SSteven Rostedt (Red Hat) } 2599d90fd774SSteven Rostedt (Red Hat) EXPORT_SYMBOL_GPL(ring_buffer_unlock_commit); 2600a4543a2fSSteven Rostedt (Red Hat) 26019826b273SSteven Rostedt (Red Hat) static noinline void 26029826b273SSteven Rostedt (Red Hat) rb_handle_timestamp(struct ring_buffer_per_cpu *cpu_buffer, 26039826b273SSteven Rostedt (Red Hat) struct rb_event_info *info) 26049826b273SSteven Rostedt (Red Hat) { 26059826b273SSteven Rostedt (Red Hat) WARN_ONCE(info->delta > (1ULL << 59), 26069826b273SSteven Rostedt (Red Hat) KERN_WARNING "Delta way too big! %llu ts=%llu write stamp = %llu\n%s", 26079826b273SSteven Rostedt (Red Hat) (unsigned long long)info->delta, 26089826b273SSteven Rostedt (Red Hat) (unsigned long long)info->ts, 26099826b273SSteven Rostedt (Red Hat) (unsigned long long)cpu_buffer->write_stamp, 26109826b273SSteven Rostedt (Red Hat) sched_clock_stable() ? "" : 26119826b273SSteven Rostedt (Red Hat) "If you just came from a suspend/resume,\n" 26129826b273SSteven Rostedt (Red Hat) "please switch to the trace global clock:\n" 26139826b273SSteven Rostedt (Red Hat) " echo global > /sys/kernel/debug/tracing/trace_clock\n"); 26149826b273SSteven Rostedt (Red Hat) info->add_timestamp = 1; 26159826b273SSteven Rostedt (Red Hat) } 26169826b273SSteven Rostedt (Red Hat) 26176634ff26SSteven Rostedt static struct ring_buffer_event * 26186634ff26SSteven Rostedt __rb_reserve_next(struct ring_buffer_per_cpu *cpu_buffer, 2619fcc742eaSSteven Rostedt (Red Hat) struct rb_event_info *info) 26206634ff26SSteven Rostedt { 26216634ff26SSteven Rostedt struct ring_buffer_event *event; 2622fcc742eaSSteven Rostedt (Red Hat) struct buffer_page *tail_page; 26236634ff26SSteven Rostedt unsigned long tail, write; 2624b7dc42fdSSteven Rostedt (Red Hat) 2625b7dc42fdSSteven Rostedt (Red Hat) /* 2626b7dc42fdSSteven Rostedt (Red Hat) * If the time delta since the last event is too big to 2627b7dc42fdSSteven Rostedt (Red Hat) * hold in the time field of the event, then we append a 2628b7dc42fdSSteven Rostedt (Red Hat) * TIME EXTEND event ahead of the data event. 2629b7dc42fdSSteven Rostedt (Red Hat) */ 2630b7dc42fdSSteven Rostedt (Red Hat) if (unlikely(info->add_timestamp)) 2631b7dc42fdSSteven Rostedt (Red Hat) info->length += RB_LEN_TIME_EXTEND; 263269d1b839SSteven Rostedt 26338573636eSSteven Rostedt (Red Hat) /* Don't let the compiler play games with cpu_buffer->tail_page */ 26348573636eSSteven Rostedt (Red Hat) tail_page = info->tail_page = READ_ONCE(cpu_buffer->tail_page); 2635fcc742eaSSteven Rostedt (Red Hat) write = local_add_return(info->length, &tail_page->write); 263677ae365eSSteven Rostedt 263777ae365eSSteven Rostedt /* set write to only the index of the write */ 263877ae365eSSteven Rostedt write &= RB_WRITE_MASK; 2639fcc742eaSSteven Rostedt (Red Hat) tail = write - info->length; 26406634ff26SSteven Rostedt 2641b7dc42fdSSteven Rostedt (Red Hat) /* 2642b7dc42fdSSteven Rostedt (Red Hat) * If this is the first commit on the page, then it has the same 2643b7dc42fdSSteven Rostedt (Red Hat) * timestamp as the page itself. 2644b7dc42fdSSteven Rostedt (Red Hat) */ 2645b7dc42fdSSteven Rostedt (Red Hat) if (!tail) 2646b7dc42fdSSteven Rostedt (Red Hat) info->delta = 0; 2647b7dc42fdSSteven Rostedt (Red Hat) 26486634ff26SSteven Rostedt /* See if we shot pass the end of this buffer page */ 2649747e94aeSSteven Rostedt if (unlikely(write > BUF_PAGE_SIZE)) 2650fcc742eaSSteven Rostedt (Red Hat) return rb_move_tail(cpu_buffer, tail, info); 26516634ff26SSteven Rostedt 26526634ff26SSteven Rostedt /* We reserved something on the buffer */ 2653b7dc42fdSSteven Rostedt (Red Hat) 26546634ff26SSteven Rostedt event = __rb_page_index(tail_page, tail); 2655fcc742eaSSteven Rostedt (Red Hat) rb_update_event(cpu_buffer, event, info); 26566634ff26SSteven Rostedt 26576634ff26SSteven Rostedt local_inc(&tail_page->entries); 26586634ff26SSteven Rostedt 2659b7dc42fdSSteven Rostedt (Red Hat) /* 2660b7dc42fdSSteven Rostedt (Red Hat) * If this is the first commit on the page, then update 2661b7dc42fdSSteven Rostedt (Red Hat) * its timestamp. 2662b7dc42fdSSteven Rostedt (Red Hat) */ 2663b7dc42fdSSteven Rostedt (Red Hat) if (!tail) 2664b7dc42fdSSteven Rostedt (Red Hat) tail_page->page->time_stamp = info->ts; 2665b7dc42fdSSteven Rostedt (Red Hat) 2666c64e148aSVaibhav Nagarnaik /* account for these added bytes */ 2667fcc742eaSSteven Rostedt (Red Hat) local_add(info->length, &cpu_buffer->entries_bytes); 2668c64e148aSVaibhav Nagarnaik 26696634ff26SSteven Rostedt return event; 26706634ff26SSteven Rostedt } 26716634ff26SSteven Rostedt 2672fa7ffb39SSteven Rostedt (Red Hat) static __always_inline struct ring_buffer_event * 267362f0b3ebSSteven Rostedt rb_reserve_next_event(struct ring_buffer *buffer, 267462f0b3ebSSteven Rostedt struct ring_buffer_per_cpu *cpu_buffer, 26751cd8d735SSteven Rostedt unsigned long length) 26767a8e76a3SSteven Rostedt { 26777a8e76a3SSteven Rostedt struct ring_buffer_event *event; 2678fcc742eaSSteven Rostedt (Red Hat) struct rb_event_info info; 2679818e3dd3SSteven Rostedt int nr_loops = 0; 2680b7dc42fdSSteven Rostedt (Red Hat) u64 diff; 26817a8e76a3SSteven Rostedt 2682fa743953SSteven Rostedt rb_start_commit(cpu_buffer); 2683fa743953SSteven Rostedt 268485bac32cSSteven Rostedt #ifdef CONFIG_RING_BUFFER_ALLOW_SWAP 268562f0b3ebSSteven Rostedt /* 268662f0b3ebSSteven Rostedt * Due to the ability to swap a cpu buffer from a buffer 268762f0b3ebSSteven Rostedt * it is possible it was swapped before we committed. 268862f0b3ebSSteven Rostedt * (committing stops a swap). We check for it here and 268962f0b3ebSSteven Rostedt * if it happened, we have to fail the write. 269062f0b3ebSSteven Rostedt */ 269162f0b3ebSSteven Rostedt barrier(); 26926aa7de05SMark Rutland if (unlikely(READ_ONCE(cpu_buffer->buffer) != buffer)) { 269362f0b3ebSSteven Rostedt local_dec(&cpu_buffer->committing); 269462f0b3ebSSteven Rostedt local_dec(&cpu_buffer->commits); 269562f0b3ebSSteven Rostedt return NULL; 269662f0b3ebSSteven Rostedt } 269785bac32cSSteven Rostedt #endif 2698b7dc42fdSSteven Rostedt (Red Hat) 2699fcc742eaSSteven Rostedt (Red Hat) info.length = rb_calculate_event_length(length); 2700a4543a2fSSteven Rostedt (Red Hat) again: 2701b7dc42fdSSteven Rostedt (Red Hat) info.add_timestamp = 0; 2702b7dc42fdSSteven Rostedt (Red Hat) info.delta = 0; 2703b7dc42fdSSteven Rostedt (Red Hat) 2704818e3dd3SSteven Rostedt /* 2705818e3dd3SSteven Rostedt * We allow for interrupts to reenter here and do a trace. 2706818e3dd3SSteven Rostedt * If one does, it will cause this original code to loop 2707818e3dd3SSteven Rostedt * back here. Even with heavy interrupts happening, this 2708818e3dd3SSteven Rostedt * should only happen a few times in a row. If this happens 2709818e3dd3SSteven Rostedt * 1000 times in a row, there must be either an interrupt 2710818e3dd3SSteven Rostedt * storm or we have something buggy. 2711818e3dd3SSteven Rostedt * Bail! 2712818e3dd3SSteven Rostedt */ 27133e89c7bbSSteven Rostedt if (RB_WARN_ON(cpu_buffer, ++nr_loops > 1000)) 2714fa743953SSteven Rostedt goto out_fail; 2715818e3dd3SSteven Rostedt 2716b7dc42fdSSteven Rostedt (Red Hat) info.ts = rb_time_stamp(cpu_buffer->buffer); 2717b7dc42fdSSteven Rostedt (Red Hat) diff = info.ts - cpu_buffer->write_stamp; 2718b7dc42fdSSteven Rostedt (Red Hat) 2719b7dc42fdSSteven Rostedt (Red Hat) /* make sure this diff is calculated here */ 2720b7dc42fdSSteven Rostedt (Red Hat) barrier(); 2721b7dc42fdSSteven Rostedt (Red Hat) 2722b7dc42fdSSteven Rostedt (Red Hat) /* Did the write stamp get updated already? */ 2723b7dc42fdSSteven Rostedt (Red Hat) if (likely(info.ts >= cpu_buffer->write_stamp)) { 2724b7dc42fdSSteven Rostedt (Red Hat) info.delta = diff; 2725b7dc42fdSSteven Rostedt (Red Hat) if (unlikely(test_time_stamp(info.delta))) 2726b7dc42fdSSteven Rostedt (Red Hat) rb_handle_timestamp(cpu_buffer, &info); 2727b7dc42fdSSteven Rostedt (Red Hat) } 2728b7dc42fdSSteven Rostedt (Red Hat) 2729fcc742eaSSteven Rostedt (Red Hat) event = __rb_reserve_next(cpu_buffer, &info); 2730fcc742eaSSteven Rostedt (Red Hat) 2731bd1b7cd3SSteven Rostedt (Red Hat) if (unlikely(PTR_ERR(event) == -EAGAIN)) { 2732bd1b7cd3SSteven Rostedt (Red Hat) if (info.add_timestamp) 2733bd1b7cd3SSteven Rostedt (Red Hat) info.length -= RB_LEN_TIME_EXTEND; 2734bf41a158SSteven Rostedt goto again; 2735bd1b7cd3SSteven Rostedt (Red Hat) } 27367a8e76a3SSteven Rostedt 2737fa743953SSteven Rostedt if (!event) 2738fa743953SSteven Rostedt goto out_fail; 2739bf41a158SSteven Rostedt 27407a8e76a3SSteven Rostedt return event; 2741fa743953SSteven Rostedt 2742fa743953SSteven Rostedt out_fail: 2743fa743953SSteven Rostedt rb_end_commit(cpu_buffer); 2744fa743953SSteven Rostedt return NULL; 27457a8e76a3SSteven Rostedt } 27467a8e76a3SSteven Rostedt 27477a8e76a3SSteven Rostedt /** 27487a8e76a3SSteven Rostedt * ring_buffer_lock_reserve - reserve a part of the buffer 27497a8e76a3SSteven Rostedt * @buffer: the ring buffer to reserve from 27507a8e76a3SSteven Rostedt * @length: the length of the data to reserve (excluding event header) 27517a8e76a3SSteven Rostedt * 27527a8e76a3SSteven Rostedt * Returns a reseverd event on the ring buffer to copy directly to. 27537a8e76a3SSteven Rostedt * The user of this interface will need to get the body to write into 27547a8e76a3SSteven Rostedt * and can use the ring_buffer_event_data() interface. 27557a8e76a3SSteven Rostedt * 27567a8e76a3SSteven Rostedt * The length is the length of the data needed, not the event length 27577a8e76a3SSteven Rostedt * which also includes the event header. 27587a8e76a3SSteven Rostedt * 27597a8e76a3SSteven Rostedt * Must be paired with ring_buffer_unlock_commit, unless NULL is returned. 27607a8e76a3SSteven Rostedt * If NULL is returned, then nothing has been allocated or locked. 27617a8e76a3SSteven Rostedt */ 27627a8e76a3SSteven Rostedt struct ring_buffer_event * 27630a987751SArnaldo Carvalho de Melo ring_buffer_lock_reserve(struct ring_buffer *buffer, unsigned long length) 27647a8e76a3SSteven Rostedt { 27657a8e76a3SSteven Rostedt struct ring_buffer_per_cpu *cpu_buffer; 27667a8e76a3SSteven Rostedt struct ring_buffer_event *event; 27675168ae50SSteven Rostedt int cpu; 27687a8e76a3SSteven Rostedt 2769bf41a158SSteven Rostedt /* If we are tracing schedule, we don't want to recurse */ 27705168ae50SSteven Rostedt preempt_disable_notrace(); 2771bf41a158SSteven Rostedt 27723205f806SSteven Rostedt (Red Hat) if (unlikely(atomic_read(&buffer->record_disabled))) 277358a09ec6SSteven Rostedt (Red Hat) goto out; 2774261842b7SSteven Rostedt 27757a8e76a3SSteven Rostedt cpu = raw_smp_processor_id(); 27767a8e76a3SSteven Rostedt 27773205f806SSteven Rostedt (Red Hat) if (unlikely(!cpumask_test_cpu(cpu, buffer->cpumask))) 2778d769041fSSteven Rostedt goto out; 27797a8e76a3SSteven Rostedt 27807a8e76a3SSteven Rostedt cpu_buffer = buffer->buffers[cpu]; 27817a8e76a3SSteven Rostedt 27823205f806SSteven Rostedt (Red Hat) if (unlikely(atomic_read(&cpu_buffer->record_disabled))) 2783d769041fSSteven Rostedt goto out; 27847a8e76a3SSteven Rostedt 27853205f806SSteven Rostedt (Red Hat) if (unlikely(length > BUF_MAX_DATA_SIZE)) 2786bf41a158SSteven Rostedt goto out; 27877a8e76a3SSteven Rostedt 278858a09ec6SSteven Rostedt (Red Hat) if (unlikely(trace_recursive_lock(cpu_buffer))) 278958a09ec6SSteven Rostedt (Red Hat) goto out; 279058a09ec6SSteven Rostedt (Red Hat) 279162f0b3ebSSteven Rostedt event = rb_reserve_next_event(buffer, cpu_buffer, length); 27927a8e76a3SSteven Rostedt if (!event) 279358a09ec6SSteven Rostedt (Red Hat) goto out_unlock; 27947a8e76a3SSteven Rostedt 27957a8e76a3SSteven Rostedt return event; 27967a8e76a3SSteven Rostedt 279758a09ec6SSteven Rostedt (Red Hat) out_unlock: 279858a09ec6SSteven Rostedt (Red Hat) trace_recursive_unlock(cpu_buffer); 2799d769041fSSteven Rostedt out: 28005168ae50SSteven Rostedt preempt_enable_notrace(); 28017a8e76a3SSteven Rostedt return NULL; 28027a8e76a3SSteven Rostedt } 2803c4f50183SRobert Richter EXPORT_SYMBOL_GPL(ring_buffer_lock_reserve); 28047a8e76a3SSteven Rostedt 2805a1863c21SSteven Rostedt /* 2806a1863c21SSteven Rostedt * Decrement the entries to the page that an event is on. 2807a1863c21SSteven Rostedt * The event does not even need to exist, only the pointer 2808a1863c21SSteven Rostedt * to the page it is on. This may only be called before the commit 2809a1863c21SSteven Rostedt * takes place. 2810a1863c21SSteven Rostedt */ 2811a1863c21SSteven Rostedt static inline void 2812a1863c21SSteven Rostedt rb_decrement_entry(struct ring_buffer_per_cpu *cpu_buffer, 2813a1863c21SSteven Rostedt struct ring_buffer_event *event) 2814a1863c21SSteven Rostedt { 2815a1863c21SSteven Rostedt unsigned long addr = (unsigned long)event; 2816a1863c21SSteven Rostedt struct buffer_page *bpage = cpu_buffer->commit_page; 2817a1863c21SSteven Rostedt struct buffer_page *start; 2818a1863c21SSteven Rostedt 2819a1863c21SSteven Rostedt addr &= PAGE_MASK; 2820a1863c21SSteven Rostedt 2821a1863c21SSteven Rostedt /* Do the likely case first */ 2822a1863c21SSteven Rostedt if (likely(bpage->page == (void *)addr)) { 2823a1863c21SSteven Rostedt local_dec(&bpage->entries); 2824a1863c21SSteven Rostedt return; 2825a1863c21SSteven Rostedt } 2826a1863c21SSteven Rostedt 2827a1863c21SSteven Rostedt /* 2828a1863c21SSteven Rostedt * Because the commit page may be on the reader page we 2829a1863c21SSteven Rostedt * start with the next page and check the end loop there. 2830a1863c21SSteven Rostedt */ 2831a1863c21SSteven Rostedt rb_inc_page(cpu_buffer, &bpage); 2832a1863c21SSteven Rostedt start = bpage; 2833a1863c21SSteven Rostedt do { 2834a1863c21SSteven Rostedt if (bpage->page == (void *)addr) { 2835a1863c21SSteven Rostedt local_dec(&bpage->entries); 2836a1863c21SSteven Rostedt return; 2837a1863c21SSteven Rostedt } 2838a1863c21SSteven Rostedt rb_inc_page(cpu_buffer, &bpage); 2839a1863c21SSteven Rostedt } while (bpage != start); 2840a1863c21SSteven Rostedt 2841a1863c21SSteven Rostedt /* commit not part of this buffer?? */ 2842a1863c21SSteven Rostedt RB_WARN_ON(cpu_buffer, 1); 2843a1863c21SSteven Rostedt } 2844a1863c21SSteven Rostedt 28457a8e76a3SSteven Rostedt /** 2846fa1b47ddSSteven Rostedt * ring_buffer_commit_discard - discard an event that has not been committed 2847fa1b47ddSSteven Rostedt * @buffer: the ring buffer 2848fa1b47ddSSteven Rostedt * @event: non committed event to discard 2849fa1b47ddSSteven Rostedt * 2850dc892f73SSteven Rostedt * Sometimes an event that is in the ring buffer needs to be ignored. 2851dc892f73SSteven Rostedt * This function lets the user discard an event in the ring buffer 2852dc892f73SSteven Rostedt * and then that event will not be read later. 2853dc892f73SSteven Rostedt * 2854dc892f73SSteven Rostedt * This function only works if it is called before the the item has been 2855dc892f73SSteven Rostedt * committed. It will try to free the event from the ring buffer 2856fa1b47ddSSteven Rostedt * if another event has not been added behind it. 2857fa1b47ddSSteven Rostedt * 2858fa1b47ddSSteven Rostedt * If another event has been added behind it, it will set the event 2859fa1b47ddSSteven Rostedt * up as discarded, and perform the commit. 2860fa1b47ddSSteven Rostedt * 2861fa1b47ddSSteven Rostedt * If this function is called, do not call ring_buffer_unlock_commit on 2862fa1b47ddSSteven Rostedt * the event. 2863fa1b47ddSSteven Rostedt */ 2864fa1b47ddSSteven Rostedt void ring_buffer_discard_commit(struct ring_buffer *buffer, 2865fa1b47ddSSteven Rostedt struct ring_buffer_event *event) 2866fa1b47ddSSteven Rostedt { 2867fa1b47ddSSteven Rostedt struct ring_buffer_per_cpu *cpu_buffer; 2868fa1b47ddSSteven Rostedt int cpu; 2869fa1b47ddSSteven Rostedt 2870fa1b47ddSSteven Rostedt /* The event is discarded regardless */ 2871f3b9aae1SFrederic Weisbecker rb_event_discard(event); 2872fa1b47ddSSteven Rostedt 2873fa743953SSteven Rostedt cpu = smp_processor_id(); 2874fa743953SSteven Rostedt cpu_buffer = buffer->buffers[cpu]; 2875fa743953SSteven Rostedt 2876fa1b47ddSSteven Rostedt /* 2877fa1b47ddSSteven Rostedt * This must only be called if the event has not been 2878fa1b47ddSSteven Rostedt * committed yet. Thus we can assume that preemption 2879fa1b47ddSSteven Rostedt * is still disabled. 2880fa1b47ddSSteven Rostedt */ 2881fa743953SSteven Rostedt RB_WARN_ON(buffer, !local_read(&cpu_buffer->committing)); 2882fa1b47ddSSteven Rostedt 2883a1863c21SSteven Rostedt rb_decrement_entry(cpu_buffer, event); 28840f2541d2SSteven Rostedt if (rb_try_to_discard(cpu_buffer, event)) 2885fa1b47ddSSteven Rostedt goto out; 2886fa1b47ddSSteven Rostedt 2887fa1b47ddSSteven Rostedt /* 2888fa1b47ddSSteven Rostedt * The commit is still visible by the reader, so we 2889a1863c21SSteven Rostedt * must still update the timestamp. 2890fa1b47ddSSteven Rostedt */ 2891a1863c21SSteven Rostedt rb_update_write_stamp(cpu_buffer, event); 2892fa1b47ddSSteven Rostedt out: 2893fa743953SSteven Rostedt rb_end_commit(cpu_buffer); 2894fa1b47ddSSteven Rostedt 289558a09ec6SSteven Rostedt (Red Hat) trace_recursive_unlock(cpu_buffer); 2896f3b9aae1SFrederic Weisbecker 28975168ae50SSteven Rostedt preempt_enable_notrace(); 2898fa1b47ddSSteven Rostedt 2899fa1b47ddSSteven Rostedt } 2900fa1b47ddSSteven Rostedt EXPORT_SYMBOL_GPL(ring_buffer_discard_commit); 2901fa1b47ddSSteven Rostedt 2902fa1b47ddSSteven Rostedt /** 29037a8e76a3SSteven Rostedt * ring_buffer_write - write data to the buffer without reserving 29047a8e76a3SSteven Rostedt * @buffer: The ring buffer to write to. 29057a8e76a3SSteven Rostedt * @length: The length of the data being written (excluding the event header) 29067a8e76a3SSteven Rostedt * @data: The data to write to the buffer. 29077a8e76a3SSteven Rostedt * 29087a8e76a3SSteven Rostedt * This is like ring_buffer_lock_reserve and ring_buffer_unlock_commit as 29097a8e76a3SSteven Rostedt * one function. If you already have the data to write to the buffer, it 29107a8e76a3SSteven Rostedt * may be easier to simply call this function. 29117a8e76a3SSteven Rostedt * 29127a8e76a3SSteven Rostedt * Note, like ring_buffer_lock_reserve, the length is the length of the data 29137a8e76a3SSteven Rostedt * and not the length of the event which would hold the header. 29147a8e76a3SSteven Rostedt */ 29157a8e76a3SSteven Rostedt int ring_buffer_write(struct ring_buffer *buffer, 29167a8e76a3SSteven Rostedt unsigned long length, 29177a8e76a3SSteven Rostedt void *data) 29187a8e76a3SSteven Rostedt { 29197a8e76a3SSteven Rostedt struct ring_buffer_per_cpu *cpu_buffer; 29207a8e76a3SSteven Rostedt struct ring_buffer_event *event; 29217a8e76a3SSteven Rostedt void *body; 29227a8e76a3SSteven Rostedt int ret = -EBUSY; 29235168ae50SSteven Rostedt int cpu; 29247a8e76a3SSteven Rostedt 29255168ae50SSteven Rostedt preempt_disable_notrace(); 2926bf41a158SSteven Rostedt 292752fbe9cdSLai Jiangshan if (atomic_read(&buffer->record_disabled)) 292852fbe9cdSLai Jiangshan goto out; 292952fbe9cdSLai Jiangshan 29307a8e76a3SSteven Rostedt cpu = raw_smp_processor_id(); 29317a8e76a3SSteven Rostedt 29329e01c1b7SRusty Russell if (!cpumask_test_cpu(cpu, buffer->cpumask)) 2933d769041fSSteven Rostedt goto out; 29347a8e76a3SSteven Rostedt 29357a8e76a3SSteven Rostedt cpu_buffer = buffer->buffers[cpu]; 29367a8e76a3SSteven Rostedt 29377a8e76a3SSteven Rostedt if (atomic_read(&cpu_buffer->record_disabled)) 29387a8e76a3SSteven Rostedt goto out; 29397a8e76a3SSteven Rostedt 2940be957c44SSteven Rostedt if (length > BUF_MAX_DATA_SIZE) 2941be957c44SSteven Rostedt goto out; 2942be957c44SSteven Rostedt 2943985e871bSSteven Rostedt (Red Hat) if (unlikely(trace_recursive_lock(cpu_buffer))) 2944985e871bSSteven Rostedt (Red Hat) goto out; 2945985e871bSSteven Rostedt (Red Hat) 294662f0b3ebSSteven Rostedt event = rb_reserve_next_event(buffer, cpu_buffer, length); 29477a8e76a3SSteven Rostedt if (!event) 2948985e871bSSteven Rostedt (Red Hat) goto out_unlock; 29497a8e76a3SSteven Rostedt 29507a8e76a3SSteven Rostedt body = rb_event_data(event); 29517a8e76a3SSteven Rostedt 29527a8e76a3SSteven Rostedt memcpy(body, data, length); 29537a8e76a3SSteven Rostedt 29547a8e76a3SSteven Rostedt rb_commit(cpu_buffer, event); 29557a8e76a3SSteven Rostedt 295615693458SSteven Rostedt (Red Hat) rb_wakeups(buffer, cpu_buffer); 295715693458SSteven Rostedt (Red Hat) 29587a8e76a3SSteven Rostedt ret = 0; 2959985e871bSSteven Rostedt (Red Hat) 2960985e871bSSteven Rostedt (Red Hat) out_unlock: 2961985e871bSSteven Rostedt (Red Hat) trace_recursive_unlock(cpu_buffer); 2962985e871bSSteven Rostedt (Red Hat) 29637a8e76a3SSteven Rostedt out: 29645168ae50SSteven Rostedt preempt_enable_notrace(); 29657a8e76a3SSteven Rostedt 29667a8e76a3SSteven Rostedt return ret; 29677a8e76a3SSteven Rostedt } 2968c4f50183SRobert Richter EXPORT_SYMBOL_GPL(ring_buffer_write); 29697a8e76a3SSteven Rostedt 2970da58834cSYaowei Bai static bool rb_per_cpu_empty(struct ring_buffer_per_cpu *cpu_buffer) 2971bf41a158SSteven Rostedt { 2972bf41a158SSteven Rostedt struct buffer_page *reader = cpu_buffer->reader_page; 297377ae365eSSteven Rostedt struct buffer_page *head = rb_set_head_page(cpu_buffer); 2974bf41a158SSteven Rostedt struct buffer_page *commit = cpu_buffer->commit_page; 2975bf41a158SSteven Rostedt 297677ae365eSSteven Rostedt /* In case of error, head will be NULL */ 297777ae365eSSteven Rostedt if (unlikely(!head)) 2978da58834cSYaowei Bai return true; 297977ae365eSSteven Rostedt 2980bf41a158SSteven Rostedt return reader->read == rb_page_commit(reader) && 2981bf41a158SSteven Rostedt (commit == reader || 2982bf41a158SSteven Rostedt (commit == head && 2983bf41a158SSteven Rostedt head->read == rb_page_commit(commit))); 2984bf41a158SSteven Rostedt } 2985bf41a158SSteven Rostedt 29867a8e76a3SSteven Rostedt /** 29877a8e76a3SSteven Rostedt * ring_buffer_record_disable - stop all writes into the buffer 29887a8e76a3SSteven Rostedt * @buffer: The ring buffer to stop writes to. 29897a8e76a3SSteven Rostedt * 29907a8e76a3SSteven Rostedt * This prevents all writes to the buffer. Any attempt to write 29917a8e76a3SSteven Rostedt * to the buffer after this will fail and return NULL. 29927a8e76a3SSteven Rostedt * 29937a8e76a3SSteven Rostedt * The caller should call synchronize_sched() after this. 29947a8e76a3SSteven Rostedt */ 29957a8e76a3SSteven Rostedt void ring_buffer_record_disable(struct ring_buffer *buffer) 29967a8e76a3SSteven Rostedt { 29977a8e76a3SSteven Rostedt atomic_inc(&buffer->record_disabled); 29987a8e76a3SSteven Rostedt } 2999c4f50183SRobert Richter EXPORT_SYMBOL_GPL(ring_buffer_record_disable); 30007a8e76a3SSteven Rostedt 30017a8e76a3SSteven Rostedt /** 30027a8e76a3SSteven Rostedt * ring_buffer_record_enable - enable writes to the buffer 30037a8e76a3SSteven Rostedt * @buffer: The ring buffer to enable writes 30047a8e76a3SSteven Rostedt * 30057a8e76a3SSteven Rostedt * Note, multiple disables will need the same number of enables 3006c41b20e7SAdam Buchbinder * to truly enable the writing (much like preempt_disable). 30077a8e76a3SSteven Rostedt */ 30087a8e76a3SSteven Rostedt void ring_buffer_record_enable(struct ring_buffer *buffer) 30097a8e76a3SSteven Rostedt { 30107a8e76a3SSteven Rostedt atomic_dec(&buffer->record_disabled); 30117a8e76a3SSteven Rostedt } 3012c4f50183SRobert Richter EXPORT_SYMBOL_GPL(ring_buffer_record_enable); 30137a8e76a3SSteven Rostedt 30147a8e76a3SSteven Rostedt /** 3015499e5470SSteven Rostedt * ring_buffer_record_off - stop all writes into the buffer 3016499e5470SSteven Rostedt * @buffer: The ring buffer to stop writes to. 3017499e5470SSteven Rostedt * 3018499e5470SSteven Rostedt * This prevents all writes to the buffer. Any attempt to write 3019499e5470SSteven Rostedt * to the buffer after this will fail and return NULL. 3020499e5470SSteven Rostedt * 3021499e5470SSteven Rostedt * This is different than ring_buffer_record_disable() as 302287abb3b1SWang Tianhong * it works like an on/off switch, where as the disable() version 3023499e5470SSteven Rostedt * must be paired with a enable(). 3024499e5470SSteven Rostedt */ 3025499e5470SSteven Rostedt void ring_buffer_record_off(struct ring_buffer *buffer) 3026499e5470SSteven Rostedt { 3027499e5470SSteven Rostedt unsigned int rd; 3028499e5470SSteven Rostedt unsigned int new_rd; 3029499e5470SSteven Rostedt 3030499e5470SSteven Rostedt do { 3031499e5470SSteven Rostedt rd = atomic_read(&buffer->record_disabled); 3032499e5470SSteven Rostedt new_rd = rd | RB_BUFFER_OFF; 3033499e5470SSteven Rostedt } while (atomic_cmpxchg(&buffer->record_disabled, rd, new_rd) != rd); 3034499e5470SSteven Rostedt } 3035499e5470SSteven Rostedt EXPORT_SYMBOL_GPL(ring_buffer_record_off); 3036499e5470SSteven Rostedt 3037499e5470SSteven Rostedt /** 3038499e5470SSteven Rostedt * ring_buffer_record_on - restart writes into the buffer 3039499e5470SSteven Rostedt * @buffer: The ring buffer to start writes to. 3040499e5470SSteven Rostedt * 3041499e5470SSteven Rostedt * This enables all writes to the buffer that was disabled by 3042499e5470SSteven Rostedt * ring_buffer_record_off(). 3043499e5470SSteven Rostedt * 3044499e5470SSteven Rostedt * This is different than ring_buffer_record_enable() as 304587abb3b1SWang Tianhong * it works like an on/off switch, where as the enable() version 3046499e5470SSteven Rostedt * must be paired with a disable(). 3047499e5470SSteven Rostedt */ 3048499e5470SSteven Rostedt void ring_buffer_record_on(struct ring_buffer *buffer) 3049499e5470SSteven Rostedt { 3050499e5470SSteven Rostedt unsigned int rd; 3051499e5470SSteven Rostedt unsigned int new_rd; 3052499e5470SSteven Rostedt 3053499e5470SSteven Rostedt do { 3054499e5470SSteven Rostedt rd = atomic_read(&buffer->record_disabled); 3055499e5470SSteven Rostedt new_rd = rd & ~RB_BUFFER_OFF; 3056499e5470SSteven Rostedt } while (atomic_cmpxchg(&buffer->record_disabled, rd, new_rd) != rd); 3057499e5470SSteven Rostedt } 3058499e5470SSteven Rostedt EXPORT_SYMBOL_GPL(ring_buffer_record_on); 3059499e5470SSteven Rostedt 3060499e5470SSteven Rostedt /** 3061499e5470SSteven Rostedt * ring_buffer_record_is_on - return true if the ring buffer can write 3062499e5470SSteven Rostedt * @buffer: The ring buffer to see if write is enabled 3063499e5470SSteven Rostedt * 3064499e5470SSteven Rostedt * Returns true if the ring buffer is in a state that it accepts writes. 3065499e5470SSteven Rostedt */ 3066499e5470SSteven Rostedt int ring_buffer_record_is_on(struct ring_buffer *buffer) 3067499e5470SSteven Rostedt { 3068499e5470SSteven Rostedt return !atomic_read(&buffer->record_disabled); 3069499e5470SSteven Rostedt } 3070499e5470SSteven Rostedt 3071499e5470SSteven Rostedt /** 30727a8e76a3SSteven Rostedt * ring_buffer_record_disable_cpu - stop all writes into the cpu_buffer 30737a8e76a3SSteven Rostedt * @buffer: The ring buffer to stop writes to. 30747a8e76a3SSteven Rostedt * @cpu: The CPU buffer to stop 30757a8e76a3SSteven Rostedt * 30767a8e76a3SSteven Rostedt * This prevents all writes to the buffer. Any attempt to write 30777a8e76a3SSteven Rostedt * to the buffer after this will fail and return NULL. 30787a8e76a3SSteven Rostedt * 30797a8e76a3SSteven Rostedt * The caller should call synchronize_sched() after this. 30807a8e76a3SSteven Rostedt */ 30817a8e76a3SSteven Rostedt void ring_buffer_record_disable_cpu(struct ring_buffer *buffer, int cpu) 30827a8e76a3SSteven Rostedt { 30837a8e76a3SSteven Rostedt struct ring_buffer_per_cpu *cpu_buffer; 30847a8e76a3SSteven Rostedt 30859e01c1b7SRusty Russell if (!cpumask_test_cpu(cpu, buffer->cpumask)) 30868aabee57SSteven Rostedt return; 30877a8e76a3SSteven Rostedt 30887a8e76a3SSteven Rostedt cpu_buffer = buffer->buffers[cpu]; 30897a8e76a3SSteven Rostedt atomic_inc(&cpu_buffer->record_disabled); 30907a8e76a3SSteven Rostedt } 3091c4f50183SRobert Richter EXPORT_SYMBOL_GPL(ring_buffer_record_disable_cpu); 30927a8e76a3SSteven Rostedt 30937a8e76a3SSteven Rostedt /** 30947a8e76a3SSteven Rostedt * ring_buffer_record_enable_cpu - enable writes to the buffer 30957a8e76a3SSteven Rostedt * @buffer: The ring buffer to enable writes 30967a8e76a3SSteven Rostedt * @cpu: The CPU to enable. 30977a8e76a3SSteven Rostedt * 30987a8e76a3SSteven Rostedt * Note, multiple disables will need the same number of enables 3099c41b20e7SAdam Buchbinder * to truly enable the writing (much like preempt_disable). 31007a8e76a3SSteven Rostedt */ 31017a8e76a3SSteven Rostedt void ring_buffer_record_enable_cpu(struct ring_buffer *buffer, int cpu) 31027a8e76a3SSteven Rostedt { 31037a8e76a3SSteven Rostedt struct ring_buffer_per_cpu *cpu_buffer; 31047a8e76a3SSteven Rostedt 31059e01c1b7SRusty Russell if (!cpumask_test_cpu(cpu, buffer->cpumask)) 31068aabee57SSteven Rostedt return; 31077a8e76a3SSteven Rostedt 31087a8e76a3SSteven Rostedt cpu_buffer = buffer->buffers[cpu]; 31097a8e76a3SSteven Rostedt atomic_dec(&cpu_buffer->record_disabled); 31107a8e76a3SSteven Rostedt } 3111c4f50183SRobert Richter EXPORT_SYMBOL_GPL(ring_buffer_record_enable_cpu); 31127a8e76a3SSteven Rostedt 3113f6195aa0SSteven Rostedt /* 3114f6195aa0SSteven Rostedt * The total entries in the ring buffer is the running counter 3115f6195aa0SSteven Rostedt * of entries entered into the ring buffer, minus the sum of 3116f6195aa0SSteven Rostedt * the entries read from the ring buffer and the number of 3117f6195aa0SSteven Rostedt * entries that were overwritten. 3118f6195aa0SSteven Rostedt */ 3119f6195aa0SSteven Rostedt static inline unsigned long 3120f6195aa0SSteven Rostedt rb_num_of_entries(struct ring_buffer_per_cpu *cpu_buffer) 3121f6195aa0SSteven Rostedt { 3122f6195aa0SSteven Rostedt return local_read(&cpu_buffer->entries) - 3123f6195aa0SSteven Rostedt (local_read(&cpu_buffer->overrun) + cpu_buffer->read); 3124f6195aa0SSteven Rostedt } 3125f6195aa0SSteven Rostedt 31267a8e76a3SSteven Rostedt /** 3127c64e148aSVaibhav Nagarnaik * ring_buffer_oldest_event_ts - get the oldest event timestamp from the buffer 3128c64e148aSVaibhav Nagarnaik * @buffer: The ring buffer 3129c64e148aSVaibhav Nagarnaik * @cpu: The per CPU buffer to read from. 3130c64e148aSVaibhav Nagarnaik */ 313150ecf2c3SYoshihiro YUNOMAE u64 ring_buffer_oldest_event_ts(struct ring_buffer *buffer, int cpu) 3132c64e148aSVaibhav Nagarnaik { 3133c64e148aSVaibhav Nagarnaik unsigned long flags; 3134c64e148aSVaibhav Nagarnaik struct ring_buffer_per_cpu *cpu_buffer; 3135c64e148aSVaibhav Nagarnaik struct buffer_page *bpage; 3136da830e58SLinus Torvalds u64 ret = 0; 3137c64e148aSVaibhav Nagarnaik 3138c64e148aSVaibhav Nagarnaik if (!cpumask_test_cpu(cpu, buffer->cpumask)) 3139c64e148aSVaibhav Nagarnaik return 0; 3140c64e148aSVaibhav Nagarnaik 3141c64e148aSVaibhav Nagarnaik cpu_buffer = buffer->buffers[cpu]; 31427115e3fcSLinus Torvalds raw_spin_lock_irqsave(&cpu_buffer->reader_lock, flags); 3143c64e148aSVaibhav Nagarnaik /* 3144c64e148aSVaibhav Nagarnaik * if the tail is on reader_page, oldest time stamp is on the reader 3145c64e148aSVaibhav Nagarnaik * page 3146c64e148aSVaibhav Nagarnaik */ 3147c64e148aSVaibhav Nagarnaik if (cpu_buffer->tail_page == cpu_buffer->reader_page) 3148c64e148aSVaibhav Nagarnaik bpage = cpu_buffer->reader_page; 3149c64e148aSVaibhav Nagarnaik else 3150c64e148aSVaibhav Nagarnaik bpage = rb_set_head_page(cpu_buffer); 315154f7be5bSSteven Rostedt if (bpage) 3152c64e148aSVaibhav Nagarnaik ret = bpage->page->time_stamp; 31537115e3fcSLinus Torvalds raw_spin_unlock_irqrestore(&cpu_buffer->reader_lock, flags); 3154c64e148aSVaibhav Nagarnaik 3155c64e148aSVaibhav Nagarnaik return ret; 3156c64e148aSVaibhav Nagarnaik } 3157c64e148aSVaibhav Nagarnaik EXPORT_SYMBOL_GPL(ring_buffer_oldest_event_ts); 3158c64e148aSVaibhav Nagarnaik 3159c64e148aSVaibhav Nagarnaik /** 3160c64e148aSVaibhav Nagarnaik * ring_buffer_bytes_cpu - get the number of bytes consumed in a cpu buffer 3161c64e148aSVaibhav Nagarnaik * @buffer: The ring buffer 3162c64e148aSVaibhav Nagarnaik * @cpu: The per CPU buffer to read from. 3163c64e148aSVaibhav Nagarnaik */ 3164c64e148aSVaibhav Nagarnaik unsigned long ring_buffer_bytes_cpu(struct ring_buffer *buffer, int cpu) 3165c64e148aSVaibhav Nagarnaik { 3166c64e148aSVaibhav Nagarnaik struct ring_buffer_per_cpu *cpu_buffer; 3167c64e148aSVaibhav Nagarnaik unsigned long ret; 3168c64e148aSVaibhav Nagarnaik 3169c64e148aSVaibhav Nagarnaik if (!cpumask_test_cpu(cpu, buffer->cpumask)) 3170c64e148aSVaibhav Nagarnaik return 0; 3171c64e148aSVaibhav Nagarnaik 3172c64e148aSVaibhav Nagarnaik cpu_buffer = buffer->buffers[cpu]; 3173c64e148aSVaibhav Nagarnaik ret = local_read(&cpu_buffer->entries_bytes) - cpu_buffer->read_bytes; 3174c64e148aSVaibhav Nagarnaik 3175c64e148aSVaibhav Nagarnaik return ret; 3176c64e148aSVaibhav Nagarnaik } 3177c64e148aSVaibhav Nagarnaik EXPORT_SYMBOL_GPL(ring_buffer_bytes_cpu); 3178c64e148aSVaibhav Nagarnaik 3179c64e148aSVaibhav Nagarnaik /** 31807a8e76a3SSteven Rostedt * ring_buffer_entries_cpu - get the number of entries in a cpu buffer 31817a8e76a3SSteven Rostedt * @buffer: The ring buffer 31827a8e76a3SSteven Rostedt * @cpu: The per CPU buffer to get the entries from. 31837a8e76a3SSteven Rostedt */ 31847a8e76a3SSteven Rostedt unsigned long ring_buffer_entries_cpu(struct ring_buffer *buffer, int cpu) 31857a8e76a3SSteven Rostedt { 31867a8e76a3SSteven Rostedt struct ring_buffer_per_cpu *cpu_buffer; 31877a8e76a3SSteven Rostedt 31889e01c1b7SRusty Russell if (!cpumask_test_cpu(cpu, buffer->cpumask)) 31898aabee57SSteven Rostedt return 0; 31907a8e76a3SSteven Rostedt 31917a8e76a3SSteven Rostedt cpu_buffer = buffer->buffers[cpu]; 3192554f786eSSteven Rostedt 3193f6195aa0SSteven Rostedt return rb_num_of_entries(cpu_buffer); 31947a8e76a3SSteven Rostedt } 3195c4f50183SRobert Richter EXPORT_SYMBOL_GPL(ring_buffer_entries_cpu); 31967a8e76a3SSteven Rostedt 31977a8e76a3SSteven Rostedt /** 3198884bfe89SSlava Pestov * ring_buffer_overrun_cpu - get the number of overruns caused by the ring 3199884bfe89SSlava Pestov * buffer wrapping around (only if RB_FL_OVERWRITE is on). 32007a8e76a3SSteven Rostedt * @buffer: The ring buffer 32017a8e76a3SSteven Rostedt * @cpu: The per CPU buffer to get the number of overruns from 32027a8e76a3SSteven Rostedt */ 32037a8e76a3SSteven Rostedt unsigned long ring_buffer_overrun_cpu(struct ring_buffer *buffer, int cpu) 32047a8e76a3SSteven Rostedt { 32057a8e76a3SSteven Rostedt struct ring_buffer_per_cpu *cpu_buffer; 32068aabee57SSteven Rostedt unsigned long ret; 32077a8e76a3SSteven Rostedt 32089e01c1b7SRusty Russell if (!cpumask_test_cpu(cpu, buffer->cpumask)) 32098aabee57SSteven Rostedt return 0; 32107a8e76a3SSteven Rostedt 32117a8e76a3SSteven Rostedt cpu_buffer = buffer->buffers[cpu]; 321277ae365eSSteven Rostedt ret = local_read(&cpu_buffer->overrun); 3213554f786eSSteven Rostedt 3214554f786eSSteven Rostedt return ret; 32157a8e76a3SSteven Rostedt } 3216c4f50183SRobert Richter EXPORT_SYMBOL_GPL(ring_buffer_overrun_cpu); 32177a8e76a3SSteven Rostedt 32187a8e76a3SSteven Rostedt /** 3219884bfe89SSlava Pestov * ring_buffer_commit_overrun_cpu - get the number of overruns caused by 3220884bfe89SSlava Pestov * commits failing due to the buffer wrapping around while there are uncommitted 3221884bfe89SSlava Pestov * events, such as during an interrupt storm. 3222f0d2c681SSteven Rostedt * @buffer: The ring buffer 3223f0d2c681SSteven Rostedt * @cpu: The per CPU buffer to get the number of overruns from 3224f0d2c681SSteven Rostedt */ 3225f0d2c681SSteven Rostedt unsigned long 3226f0d2c681SSteven Rostedt ring_buffer_commit_overrun_cpu(struct ring_buffer *buffer, int cpu) 3227f0d2c681SSteven Rostedt { 3228f0d2c681SSteven Rostedt struct ring_buffer_per_cpu *cpu_buffer; 3229f0d2c681SSteven Rostedt unsigned long ret; 3230f0d2c681SSteven Rostedt 3231f0d2c681SSteven Rostedt if (!cpumask_test_cpu(cpu, buffer->cpumask)) 3232f0d2c681SSteven Rostedt return 0; 3233f0d2c681SSteven Rostedt 3234f0d2c681SSteven Rostedt cpu_buffer = buffer->buffers[cpu]; 323577ae365eSSteven Rostedt ret = local_read(&cpu_buffer->commit_overrun); 3236f0d2c681SSteven Rostedt 3237f0d2c681SSteven Rostedt return ret; 3238f0d2c681SSteven Rostedt } 3239f0d2c681SSteven Rostedt EXPORT_SYMBOL_GPL(ring_buffer_commit_overrun_cpu); 3240f0d2c681SSteven Rostedt 3241f0d2c681SSteven Rostedt /** 3242884bfe89SSlava Pestov * ring_buffer_dropped_events_cpu - get the number of dropped events caused by 3243884bfe89SSlava Pestov * the ring buffer filling up (only if RB_FL_OVERWRITE is off). 3244884bfe89SSlava Pestov * @buffer: The ring buffer 3245884bfe89SSlava Pestov * @cpu: The per CPU buffer to get the number of overruns from 3246884bfe89SSlava Pestov */ 3247884bfe89SSlava Pestov unsigned long 3248884bfe89SSlava Pestov ring_buffer_dropped_events_cpu(struct ring_buffer *buffer, int cpu) 3249884bfe89SSlava Pestov { 3250884bfe89SSlava Pestov struct ring_buffer_per_cpu *cpu_buffer; 3251884bfe89SSlava Pestov unsigned long ret; 3252884bfe89SSlava Pestov 3253884bfe89SSlava Pestov if (!cpumask_test_cpu(cpu, buffer->cpumask)) 3254884bfe89SSlava Pestov return 0; 3255884bfe89SSlava Pestov 3256884bfe89SSlava Pestov cpu_buffer = buffer->buffers[cpu]; 3257884bfe89SSlava Pestov ret = local_read(&cpu_buffer->dropped_events); 3258884bfe89SSlava Pestov 3259884bfe89SSlava Pestov return ret; 3260884bfe89SSlava Pestov } 3261884bfe89SSlava Pestov EXPORT_SYMBOL_GPL(ring_buffer_dropped_events_cpu); 3262884bfe89SSlava Pestov 3263884bfe89SSlava Pestov /** 3264ad964704SSteven Rostedt (Red Hat) * ring_buffer_read_events_cpu - get the number of events successfully read 3265ad964704SSteven Rostedt (Red Hat) * @buffer: The ring buffer 3266ad964704SSteven Rostedt (Red Hat) * @cpu: The per CPU buffer to get the number of events read 3267ad964704SSteven Rostedt (Red Hat) */ 3268ad964704SSteven Rostedt (Red Hat) unsigned long 3269ad964704SSteven Rostedt (Red Hat) ring_buffer_read_events_cpu(struct ring_buffer *buffer, int cpu) 3270ad964704SSteven Rostedt (Red Hat) { 3271ad964704SSteven Rostedt (Red Hat) struct ring_buffer_per_cpu *cpu_buffer; 3272ad964704SSteven Rostedt (Red Hat) 3273ad964704SSteven Rostedt (Red Hat) if (!cpumask_test_cpu(cpu, buffer->cpumask)) 3274ad964704SSteven Rostedt (Red Hat) return 0; 3275ad964704SSteven Rostedt (Red Hat) 3276ad964704SSteven Rostedt (Red Hat) cpu_buffer = buffer->buffers[cpu]; 3277ad964704SSteven Rostedt (Red Hat) return cpu_buffer->read; 3278ad964704SSteven Rostedt (Red Hat) } 3279ad964704SSteven Rostedt (Red Hat) EXPORT_SYMBOL_GPL(ring_buffer_read_events_cpu); 3280ad964704SSteven Rostedt (Red Hat) 3281ad964704SSteven Rostedt (Red Hat) /** 32827a8e76a3SSteven Rostedt * ring_buffer_entries - get the number of entries in a buffer 32837a8e76a3SSteven Rostedt * @buffer: The ring buffer 32847a8e76a3SSteven Rostedt * 32857a8e76a3SSteven Rostedt * Returns the total number of entries in the ring buffer 32867a8e76a3SSteven Rostedt * (all CPU entries) 32877a8e76a3SSteven Rostedt */ 32887a8e76a3SSteven Rostedt unsigned long ring_buffer_entries(struct ring_buffer *buffer) 32897a8e76a3SSteven Rostedt { 32907a8e76a3SSteven Rostedt struct ring_buffer_per_cpu *cpu_buffer; 32917a8e76a3SSteven Rostedt unsigned long entries = 0; 32927a8e76a3SSteven Rostedt int cpu; 32937a8e76a3SSteven Rostedt 32947a8e76a3SSteven Rostedt /* if you care about this being correct, lock the buffer */ 32957a8e76a3SSteven Rostedt for_each_buffer_cpu(buffer, cpu) { 32967a8e76a3SSteven Rostedt cpu_buffer = buffer->buffers[cpu]; 3297f6195aa0SSteven Rostedt entries += rb_num_of_entries(cpu_buffer); 32987a8e76a3SSteven Rostedt } 32997a8e76a3SSteven Rostedt 33007a8e76a3SSteven Rostedt return entries; 33017a8e76a3SSteven Rostedt } 3302c4f50183SRobert Richter EXPORT_SYMBOL_GPL(ring_buffer_entries); 33037a8e76a3SSteven Rostedt 33047a8e76a3SSteven Rostedt /** 330567b394f7SJiri Olsa * ring_buffer_overruns - get the number of overruns in buffer 33067a8e76a3SSteven Rostedt * @buffer: The ring buffer 33077a8e76a3SSteven Rostedt * 33087a8e76a3SSteven Rostedt * Returns the total number of overruns in the ring buffer 33097a8e76a3SSteven Rostedt * (all CPU entries) 33107a8e76a3SSteven Rostedt */ 33117a8e76a3SSteven Rostedt unsigned long ring_buffer_overruns(struct ring_buffer *buffer) 33127a8e76a3SSteven Rostedt { 33137a8e76a3SSteven Rostedt struct ring_buffer_per_cpu *cpu_buffer; 33147a8e76a3SSteven Rostedt unsigned long overruns = 0; 33157a8e76a3SSteven Rostedt int cpu; 33167a8e76a3SSteven Rostedt 33177a8e76a3SSteven Rostedt /* if you care about this being correct, lock the buffer */ 33187a8e76a3SSteven Rostedt for_each_buffer_cpu(buffer, cpu) { 33197a8e76a3SSteven Rostedt cpu_buffer = buffer->buffers[cpu]; 332077ae365eSSteven Rostedt overruns += local_read(&cpu_buffer->overrun); 33217a8e76a3SSteven Rostedt } 33227a8e76a3SSteven Rostedt 33237a8e76a3SSteven Rostedt return overruns; 33247a8e76a3SSteven Rostedt } 3325c4f50183SRobert Richter EXPORT_SYMBOL_GPL(ring_buffer_overruns); 33267a8e76a3SSteven Rostedt 3327642edba5SSteven Rostedt static void rb_iter_reset(struct ring_buffer_iter *iter) 33287a8e76a3SSteven Rostedt { 33297a8e76a3SSteven Rostedt struct ring_buffer_per_cpu *cpu_buffer = iter->cpu_buffer; 33307a8e76a3SSteven Rostedt 3331d769041fSSteven Rostedt /* Iterator usage is expected to have record disabled */ 3332d769041fSSteven Rostedt iter->head_page = cpu_buffer->reader_page; 33336f807acdSSteven Rostedt iter->head = cpu_buffer->reader_page->read; 3334651e22f2SSteven Rostedt (Red Hat) 3335651e22f2SSteven Rostedt (Red Hat) iter->cache_reader_page = iter->head_page; 333624607f11SSteven Rostedt (Red Hat) iter->cache_read = cpu_buffer->read; 3337651e22f2SSteven Rostedt (Red Hat) 3338d769041fSSteven Rostedt if (iter->head) 3339d769041fSSteven Rostedt iter->read_stamp = cpu_buffer->read_stamp; 3340d769041fSSteven Rostedt else 3341abc9b56dSSteven Rostedt iter->read_stamp = iter->head_page->page->time_stamp; 3342642edba5SSteven Rostedt } 3343f83c9d0fSSteven Rostedt 3344642edba5SSteven Rostedt /** 3345642edba5SSteven Rostedt * ring_buffer_iter_reset - reset an iterator 3346642edba5SSteven Rostedt * @iter: The iterator to reset 3347642edba5SSteven Rostedt * 3348642edba5SSteven Rostedt * Resets the iterator, so that it will start from the beginning 3349642edba5SSteven Rostedt * again. 3350642edba5SSteven Rostedt */ 3351642edba5SSteven Rostedt void ring_buffer_iter_reset(struct ring_buffer_iter *iter) 3352642edba5SSteven Rostedt { 3353554f786eSSteven Rostedt struct ring_buffer_per_cpu *cpu_buffer; 3354642edba5SSteven Rostedt unsigned long flags; 3355642edba5SSteven Rostedt 3356554f786eSSteven Rostedt if (!iter) 3357554f786eSSteven Rostedt return; 3358554f786eSSteven Rostedt 3359554f786eSSteven Rostedt cpu_buffer = iter->cpu_buffer; 3360554f786eSSteven Rostedt 33615389f6faSThomas Gleixner raw_spin_lock_irqsave(&cpu_buffer->reader_lock, flags); 3362642edba5SSteven Rostedt rb_iter_reset(iter); 33635389f6faSThomas Gleixner raw_spin_unlock_irqrestore(&cpu_buffer->reader_lock, flags); 33647a8e76a3SSteven Rostedt } 3365c4f50183SRobert Richter EXPORT_SYMBOL_GPL(ring_buffer_iter_reset); 33667a8e76a3SSteven Rostedt 33677a8e76a3SSteven Rostedt /** 33687a8e76a3SSteven Rostedt * ring_buffer_iter_empty - check if an iterator has no more to read 33697a8e76a3SSteven Rostedt * @iter: The iterator to check 33707a8e76a3SSteven Rostedt */ 33717a8e76a3SSteven Rostedt int ring_buffer_iter_empty(struct ring_buffer_iter *iter) 33727a8e76a3SSteven Rostedt { 33737a8e76a3SSteven Rostedt struct ring_buffer_per_cpu *cpu_buffer; 337478f7a45dSSteven Rostedt (VMware) struct buffer_page *reader; 337578f7a45dSSteven Rostedt (VMware) struct buffer_page *head_page; 337678f7a45dSSteven Rostedt (VMware) struct buffer_page *commit_page; 337778f7a45dSSteven Rostedt (VMware) unsigned commit; 33787a8e76a3SSteven Rostedt 33797a8e76a3SSteven Rostedt cpu_buffer = iter->cpu_buffer; 33807a8e76a3SSteven Rostedt 338178f7a45dSSteven Rostedt (VMware) /* Remember, trace recording is off when iterator is in use */ 338278f7a45dSSteven Rostedt (VMware) reader = cpu_buffer->reader_page; 338378f7a45dSSteven Rostedt (VMware) head_page = cpu_buffer->head_page; 338478f7a45dSSteven Rostedt (VMware) commit_page = cpu_buffer->commit_page; 338578f7a45dSSteven Rostedt (VMware) commit = rb_page_commit(commit_page); 338678f7a45dSSteven Rostedt (VMware) 338778f7a45dSSteven Rostedt (VMware) return ((iter->head_page == commit_page && iter->head == commit) || 338878f7a45dSSteven Rostedt (VMware) (iter->head_page == reader && commit_page == head_page && 338978f7a45dSSteven Rostedt (VMware) head_page->read == commit && 339078f7a45dSSteven Rostedt (VMware) iter->head == rb_page_commit(cpu_buffer->reader_page))); 33917a8e76a3SSteven Rostedt } 3392c4f50183SRobert Richter EXPORT_SYMBOL_GPL(ring_buffer_iter_empty); 33937a8e76a3SSteven Rostedt 33947a8e76a3SSteven Rostedt static void 33957a8e76a3SSteven Rostedt rb_update_read_stamp(struct ring_buffer_per_cpu *cpu_buffer, 33967a8e76a3SSteven Rostedt struct ring_buffer_event *event) 33977a8e76a3SSteven Rostedt { 33987a8e76a3SSteven Rostedt u64 delta; 33997a8e76a3SSteven Rostedt 3400334d4169SLai Jiangshan switch (event->type_len) { 34017a8e76a3SSteven Rostedt case RINGBUF_TYPE_PADDING: 34027a8e76a3SSteven Rostedt return; 34037a8e76a3SSteven Rostedt 34047a8e76a3SSteven Rostedt case RINGBUF_TYPE_TIME_EXTEND: 34057a8e76a3SSteven Rostedt delta = event->array[0]; 34067a8e76a3SSteven Rostedt delta <<= TS_SHIFT; 34077a8e76a3SSteven Rostedt delta += event->time_delta; 34087a8e76a3SSteven Rostedt cpu_buffer->read_stamp += delta; 34097a8e76a3SSteven Rostedt return; 34107a8e76a3SSteven Rostedt 34117a8e76a3SSteven Rostedt case RINGBUF_TYPE_TIME_STAMP: 34127a8e76a3SSteven Rostedt /* FIXME: not implemented */ 34137a8e76a3SSteven Rostedt return; 34147a8e76a3SSteven Rostedt 34157a8e76a3SSteven Rostedt case RINGBUF_TYPE_DATA: 34167a8e76a3SSteven Rostedt cpu_buffer->read_stamp += event->time_delta; 34177a8e76a3SSteven Rostedt return; 34187a8e76a3SSteven Rostedt 34197a8e76a3SSteven Rostedt default: 34207a8e76a3SSteven Rostedt BUG(); 34217a8e76a3SSteven Rostedt } 34227a8e76a3SSteven Rostedt return; 34237a8e76a3SSteven Rostedt } 34247a8e76a3SSteven Rostedt 34257a8e76a3SSteven Rostedt static void 34267a8e76a3SSteven Rostedt rb_update_iter_read_stamp(struct ring_buffer_iter *iter, 34277a8e76a3SSteven Rostedt struct ring_buffer_event *event) 34287a8e76a3SSteven Rostedt { 34297a8e76a3SSteven Rostedt u64 delta; 34307a8e76a3SSteven Rostedt 3431334d4169SLai Jiangshan switch (event->type_len) { 34327a8e76a3SSteven Rostedt case RINGBUF_TYPE_PADDING: 34337a8e76a3SSteven Rostedt return; 34347a8e76a3SSteven Rostedt 34357a8e76a3SSteven Rostedt case RINGBUF_TYPE_TIME_EXTEND: 34367a8e76a3SSteven Rostedt delta = event->array[0]; 34377a8e76a3SSteven Rostedt delta <<= TS_SHIFT; 34387a8e76a3SSteven Rostedt delta += event->time_delta; 34397a8e76a3SSteven Rostedt iter->read_stamp += delta; 34407a8e76a3SSteven Rostedt return; 34417a8e76a3SSteven Rostedt 34427a8e76a3SSteven Rostedt case RINGBUF_TYPE_TIME_STAMP: 34437a8e76a3SSteven Rostedt /* FIXME: not implemented */ 34447a8e76a3SSteven Rostedt return; 34457a8e76a3SSteven Rostedt 34467a8e76a3SSteven Rostedt case RINGBUF_TYPE_DATA: 34477a8e76a3SSteven Rostedt iter->read_stamp += event->time_delta; 34487a8e76a3SSteven Rostedt return; 34497a8e76a3SSteven Rostedt 34507a8e76a3SSteven Rostedt default: 34517a8e76a3SSteven Rostedt BUG(); 34527a8e76a3SSteven Rostedt } 34537a8e76a3SSteven Rostedt return; 34547a8e76a3SSteven Rostedt } 34557a8e76a3SSteven Rostedt 3456d769041fSSteven Rostedt static struct buffer_page * 3457d769041fSSteven Rostedt rb_get_reader_page(struct ring_buffer_per_cpu *cpu_buffer) 34587a8e76a3SSteven Rostedt { 3459d769041fSSteven Rostedt struct buffer_page *reader = NULL; 346066a8cb95SSteven Rostedt unsigned long overwrite; 3461d769041fSSteven Rostedt unsigned long flags; 3462818e3dd3SSteven Rostedt int nr_loops = 0; 346377ae365eSSteven Rostedt int ret; 3464d769041fSSteven Rostedt 34653e03fb7fSSteven Rostedt local_irq_save(flags); 34660199c4e6SThomas Gleixner arch_spin_lock(&cpu_buffer->lock); 3467d769041fSSteven Rostedt 3468d769041fSSteven Rostedt again: 3469818e3dd3SSteven Rostedt /* 3470818e3dd3SSteven Rostedt * This should normally only loop twice. But because the 3471818e3dd3SSteven Rostedt * start of the reader inserts an empty page, it causes 3472818e3dd3SSteven Rostedt * a case where we will loop three times. There should be no 3473818e3dd3SSteven Rostedt * reason to loop four times (that I know of). 3474818e3dd3SSteven Rostedt */ 34753e89c7bbSSteven Rostedt if (RB_WARN_ON(cpu_buffer, ++nr_loops > 3)) { 3476818e3dd3SSteven Rostedt reader = NULL; 3477818e3dd3SSteven Rostedt goto out; 3478818e3dd3SSteven Rostedt } 3479818e3dd3SSteven Rostedt 3480d769041fSSteven Rostedt reader = cpu_buffer->reader_page; 3481d769041fSSteven Rostedt 3482d769041fSSteven Rostedt /* If there's more to read, return this page */ 3483bf41a158SSteven Rostedt if (cpu_buffer->reader_page->read < rb_page_size(reader)) 3484d769041fSSteven Rostedt goto out; 3485d769041fSSteven Rostedt 3486d769041fSSteven Rostedt /* Never should we have an index greater than the size */ 34873e89c7bbSSteven Rostedt if (RB_WARN_ON(cpu_buffer, 34883e89c7bbSSteven Rostedt cpu_buffer->reader_page->read > rb_page_size(reader))) 34893e89c7bbSSteven Rostedt goto out; 3490d769041fSSteven Rostedt 3491d769041fSSteven Rostedt /* check if we caught up to the tail */ 3492d769041fSSteven Rostedt reader = NULL; 3493bf41a158SSteven Rostedt if (cpu_buffer->commit_page == cpu_buffer->reader_page) 3494d769041fSSteven Rostedt goto out; 34957a8e76a3SSteven Rostedt 3496a5fb8331SSteven Rostedt /* Don't bother swapping if the ring buffer is empty */ 3497a5fb8331SSteven Rostedt if (rb_num_of_entries(cpu_buffer) == 0) 3498a5fb8331SSteven Rostedt goto out; 3499a5fb8331SSteven Rostedt 35007a8e76a3SSteven Rostedt /* 3501d769041fSSteven Rostedt * Reset the reader page to size zero. 35027a8e76a3SSteven Rostedt */ 350377ae365eSSteven Rostedt local_set(&cpu_buffer->reader_page->write, 0); 350477ae365eSSteven Rostedt local_set(&cpu_buffer->reader_page->entries, 0); 350577ae365eSSteven Rostedt local_set(&cpu_buffer->reader_page->page->commit, 0); 3506ff0ff84aSSteven Rostedt cpu_buffer->reader_page->real_end = 0; 3507d769041fSSteven Rostedt 350877ae365eSSteven Rostedt spin: 350977ae365eSSteven Rostedt /* 351077ae365eSSteven Rostedt * Splice the empty reader page into the list around the head. 351177ae365eSSteven Rostedt */ 351277ae365eSSteven Rostedt reader = rb_set_head_page(cpu_buffer); 351354f7be5bSSteven Rostedt if (!reader) 351454f7be5bSSteven Rostedt goto out; 35150e1ff5d7SSteven Rostedt cpu_buffer->reader_page->list.next = rb_list_head(reader->list.next); 3516d769041fSSteven Rostedt cpu_buffer->reader_page->list.prev = reader->list.prev; 3517bf41a158SSteven Rostedt 35183adc54faSSteven Rostedt /* 35193adc54faSSteven Rostedt * cpu_buffer->pages just needs to point to the buffer, it 35203adc54faSSteven Rostedt * has no specific buffer page to point to. Lets move it out 352125985edcSLucas De Marchi * of our way so we don't accidentally swap it. 35223adc54faSSteven Rostedt */ 35233adc54faSSteven Rostedt cpu_buffer->pages = reader->list.prev; 35243adc54faSSteven Rostedt 352577ae365eSSteven Rostedt /* The reader page will be pointing to the new head */ 352677ae365eSSteven Rostedt rb_set_list_to_head(cpu_buffer, &cpu_buffer->reader_page->list); 3527d769041fSSteven Rostedt 3528d769041fSSteven Rostedt /* 352966a8cb95SSteven Rostedt * We want to make sure we read the overruns after we set up our 353066a8cb95SSteven Rostedt * pointers to the next object. The writer side does a 353166a8cb95SSteven Rostedt * cmpxchg to cross pages which acts as the mb on the writer 353266a8cb95SSteven Rostedt * side. Note, the reader will constantly fail the swap 353366a8cb95SSteven Rostedt * while the writer is updating the pointers, so this 353466a8cb95SSteven Rostedt * guarantees that the overwrite recorded here is the one we 353566a8cb95SSteven Rostedt * want to compare with the last_overrun. 353666a8cb95SSteven Rostedt */ 353766a8cb95SSteven Rostedt smp_mb(); 353866a8cb95SSteven Rostedt overwrite = local_read(&(cpu_buffer->overrun)); 353966a8cb95SSteven Rostedt 354066a8cb95SSteven Rostedt /* 354177ae365eSSteven Rostedt * Here's the tricky part. 354277ae365eSSteven Rostedt * 354377ae365eSSteven Rostedt * We need to move the pointer past the header page. 354477ae365eSSteven Rostedt * But we can only do that if a writer is not currently 354577ae365eSSteven Rostedt * moving it. The page before the header page has the 354677ae365eSSteven Rostedt * flag bit '1' set if it is pointing to the page we want. 354777ae365eSSteven Rostedt * but if the writer is in the process of moving it 354877ae365eSSteven Rostedt * than it will be '2' or already moved '0'. 3549d769041fSSteven Rostedt */ 3550d769041fSSteven Rostedt 355177ae365eSSteven Rostedt ret = rb_head_page_replace(reader, cpu_buffer->reader_page); 355277ae365eSSteven Rostedt 355377ae365eSSteven Rostedt /* 355477ae365eSSteven Rostedt * If we did not convert it, then we must try again. 355577ae365eSSteven Rostedt */ 355677ae365eSSteven Rostedt if (!ret) 355777ae365eSSteven Rostedt goto spin; 355877ae365eSSteven Rostedt 355977ae365eSSteven Rostedt /* 356077ae365eSSteven Rostedt * Yeah! We succeeded in replacing the page. 356177ae365eSSteven Rostedt * 356277ae365eSSteven Rostedt * Now make the new head point back to the reader page. 356377ae365eSSteven Rostedt */ 35645ded3dc6SDavid Sharp rb_list_head(reader->list.next)->prev = &cpu_buffer->reader_page->list; 35657a8e76a3SSteven Rostedt rb_inc_page(cpu_buffer, &cpu_buffer->head_page); 3566d769041fSSteven Rostedt 3567d769041fSSteven Rostedt /* Finally update the reader page to the new head */ 3568d769041fSSteven Rostedt cpu_buffer->reader_page = reader; 3569b81f472aSSteven Rostedt (Red Hat) cpu_buffer->reader_page->read = 0; 3570d769041fSSteven Rostedt 357166a8cb95SSteven Rostedt if (overwrite != cpu_buffer->last_overrun) { 357266a8cb95SSteven Rostedt cpu_buffer->lost_events = overwrite - cpu_buffer->last_overrun; 357366a8cb95SSteven Rostedt cpu_buffer->last_overrun = overwrite; 357466a8cb95SSteven Rostedt } 357566a8cb95SSteven Rostedt 3576d769041fSSteven Rostedt goto again; 3577d769041fSSteven Rostedt 3578d769041fSSteven Rostedt out: 3579b81f472aSSteven Rostedt (Red Hat) /* Update the read_stamp on the first event */ 3580b81f472aSSteven Rostedt (Red Hat) if (reader && reader->read == 0) 3581b81f472aSSteven Rostedt (Red Hat) cpu_buffer->read_stamp = reader->page->time_stamp; 3582b81f472aSSteven Rostedt (Red Hat) 35830199c4e6SThomas Gleixner arch_spin_unlock(&cpu_buffer->lock); 35843e03fb7fSSteven Rostedt local_irq_restore(flags); 3585d769041fSSteven Rostedt 3586d769041fSSteven Rostedt return reader; 35877a8e76a3SSteven Rostedt } 35887a8e76a3SSteven Rostedt 3589d769041fSSteven Rostedt static void rb_advance_reader(struct ring_buffer_per_cpu *cpu_buffer) 3590d769041fSSteven Rostedt { 3591d769041fSSteven Rostedt struct ring_buffer_event *event; 3592d769041fSSteven Rostedt struct buffer_page *reader; 3593d769041fSSteven Rostedt unsigned length; 3594d769041fSSteven Rostedt 3595d769041fSSteven Rostedt reader = rb_get_reader_page(cpu_buffer); 3596d769041fSSteven Rostedt 3597d769041fSSteven Rostedt /* This function should not be called when buffer is empty */ 35983e89c7bbSSteven Rostedt if (RB_WARN_ON(cpu_buffer, !reader)) 35993e89c7bbSSteven Rostedt return; 3600d769041fSSteven Rostedt 3601d769041fSSteven Rostedt event = rb_reader_event(cpu_buffer); 36027a8e76a3SSteven Rostedt 3603a1863c21SSteven Rostedt if (event->type_len <= RINGBUF_TYPE_DATA_TYPE_LEN_MAX) 3604e4906effSSteven Rostedt cpu_buffer->read++; 36057a8e76a3SSteven Rostedt 36067a8e76a3SSteven Rostedt rb_update_read_stamp(cpu_buffer, event); 36077a8e76a3SSteven Rostedt 3608d769041fSSteven Rostedt length = rb_event_length(event); 36096f807acdSSteven Rostedt cpu_buffer->reader_page->read += length; 36107a8e76a3SSteven Rostedt } 36117a8e76a3SSteven Rostedt 36127a8e76a3SSteven Rostedt static void rb_advance_iter(struct ring_buffer_iter *iter) 36137a8e76a3SSteven Rostedt { 36147a8e76a3SSteven Rostedt struct ring_buffer_per_cpu *cpu_buffer; 36157a8e76a3SSteven Rostedt struct ring_buffer_event *event; 36167a8e76a3SSteven Rostedt unsigned length; 36177a8e76a3SSteven Rostedt 36187a8e76a3SSteven Rostedt cpu_buffer = iter->cpu_buffer; 36197a8e76a3SSteven Rostedt 36207a8e76a3SSteven Rostedt /* 36217a8e76a3SSteven Rostedt * Check if we are at the end of the buffer. 36227a8e76a3SSteven Rostedt */ 3623bf41a158SSteven Rostedt if (iter->head >= rb_page_size(iter->head_page)) { 3624ea05b57cSSteven Rostedt /* discarded commits can make the page empty */ 3625ea05b57cSSteven Rostedt if (iter->head_page == cpu_buffer->commit_page) 36263e89c7bbSSteven Rostedt return; 3627d769041fSSteven Rostedt rb_inc_iter(iter); 36287a8e76a3SSteven Rostedt return; 36297a8e76a3SSteven Rostedt } 36307a8e76a3SSteven Rostedt 36317a8e76a3SSteven Rostedt event = rb_iter_head_event(iter); 36327a8e76a3SSteven Rostedt 36337a8e76a3SSteven Rostedt length = rb_event_length(event); 36347a8e76a3SSteven Rostedt 36357a8e76a3SSteven Rostedt /* 36367a8e76a3SSteven Rostedt * This should not be called to advance the header if we are 36377a8e76a3SSteven Rostedt * at the tail of the buffer. 36387a8e76a3SSteven Rostedt */ 36393e89c7bbSSteven Rostedt if (RB_WARN_ON(cpu_buffer, 3640f536aafcSSteven Rostedt (iter->head_page == cpu_buffer->commit_page) && 36413e89c7bbSSteven Rostedt (iter->head + length > rb_commit_index(cpu_buffer)))) 36423e89c7bbSSteven Rostedt return; 36437a8e76a3SSteven Rostedt 36447a8e76a3SSteven Rostedt rb_update_iter_read_stamp(iter, event); 36457a8e76a3SSteven Rostedt 36467a8e76a3SSteven Rostedt iter->head += length; 36477a8e76a3SSteven Rostedt 36487a8e76a3SSteven Rostedt /* check for end of page padding */ 3649bf41a158SSteven Rostedt if ((iter->head >= rb_page_size(iter->head_page)) && 3650bf41a158SSteven Rostedt (iter->head_page != cpu_buffer->commit_page)) 3651771e0384SSteven Rostedt rb_inc_iter(iter); 36527a8e76a3SSteven Rostedt } 36537a8e76a3SSteven Rostedt 365466a8cb95SSteven Rostedt static int rb_lost_events(struct ring_buffer_per_cpu *cpu_buffer) 365566a8cb95SSteven Rostedt { 365666a8cb95SSteven Rostedt return cpu_buffer->lost_events; 365766a8cb95SSteven Rostedt } 365866a8cb95SSteven Rostedt 3659f83c9d0fSSteven Rostedt static struct ring_buffer_event * 366066a8cb95SSteven Rostedt rb_buffer_peek(struct ring_buffer_per_cpu *cpu_buffer, u64 *ts, 366166a8cb95SSteven Rostedt unsigned long *lost_events) 36627a8e76a3SSteven Rostedt { 36637a8e76a3SSteven Rostedt struct ring_buffer_event *event; 3664d769041fSSteven Rostedt struct buffer_page *reader; 3665818e3dd3SSteven Rostedt int nr_loops = 0; 36667a8e76a3SSteven Rostedt 36677a8e76a3SSteven Rostedt again: 3668818e3dd3SSteven Rostedt /* 366969d1b839SSteven Rostedt * We repeat when a time extend is encountered. 367069d1b839SSteven Rostedt * Since the time extend is always attached to a data event, 367169d1b839SSteven Rostedt * we should never loop more than once. 367269d1b839SSteven Rostedt * (We never hit the following condition more than twice). 3673818e3dd3SSteven Rostedt */ 367469d1b839SSteven Rostedt if (RB_WARN_ON(cpu_buffer, ++nr_loops > 2)) 3675818e3dd3SSteven Rostedt return NULL; 3676818e3dd3SSteven Rostedt 3677d769041fSSteven Rostedt reader = rb_get_reader_page(cpu_buffer); 3678d769041fSSteven Rostedt if (!reader) 36797a8e76a3SSteven Rostedt return NULL; 36807a8e76a3SSteven Rostedt 3681d769041fSSteven Rostedt event = rb_reader_event(cpu_buffer); 36827a8e76a3SSteven Rostedt 3683334d4169SLai Jiangshan switch (event->type_len) { 36847a8e76a3SSteven Rostedt case RINGBUF_TYPE_PADDING: 36852d622719STom Zanussi if (rb_null_event(event)) 3686bf41a158SSteven Rostedt RB_WARN_ON(cpu_buffer, 1); 36872d622719STom Zanussi /* 36882d622719STom Zanussi * Because the writer could be discarding every 36892d622719STom Zanussi * event it creates (which would probably be bad) 36902d622719STom Zanussi * if we were to go back to "again" then we may never 36912d622719STom Zanussi * catch up, and will trigger the warn on, or lock 36922d622719STom Zanussi * the box. Return the padding, and we will release 36932d622719STom Zanussi * the current locks, and try again. 36942d622719STom Zanussi */ 36952d622719STom Zanussi return event; 36967a8e76a3SSteven Rostedt 36977a8e76a3SSteven Rostedt case RINGBUF_TYPE_TIME_EXTEND: 36987a8e76a3SSteven Rostedt /* Internal data, OK to advance */ 3699d769041fSSteven Rostedt rb_advance_reader(cpu_buffer); 37007a8e76a3SSteven Rostedt goto again; 37017a8e76a3SSteven Rostedt 37027a8e76a3SSteven Rostedt case RINGBUF_TYPE_TIME_STAMP: 37037a8e76a3SSteven Rostedt /* FIXME: not implemented */ 3704d769041fSSteven Rostedt rb_advance_reader(cpu_buffer); 37057a8e76a3SSteven Rostedt goto again; 37067a8e76a3SSteven Rostedt 37077a8e76a3SSteven Rostedt case RINGBUF_TYPE_DATA: 37087a8e76a3SSteven Rostedt if (ts) { 37097a8e76a3SSteven Rostedt *ts = cpu_buffer->read_stamp + event->time_delta; 3710d8eeb2d3SRobert Richter ring_buffer_normalize_time_stamp(cpu_buffer->buffer, 371137886f6aSSteven Rostedt cpu_buffer->cpu, ts); 37127a8e76a3SSteven Rostedt } 371366a8cb95SSteven Rostedt if (lost_events) 371466a8cb95SSteven Rostedt *lost_events = rb_lost_events(cpu_buffer); 37157a8e76a3SSteven Rostedt return event; 37167a8e76a3SSteven Rostedt 37177a8e76a3SSteven Rostedt default: 37187a8e76a3SSteven Rostedt BUG(); 37197a8e76a3SSteven Rostedt } 37207a8e76a3SSteven Rostedt 37217a8e76a3SSteven Rostedt return NULL; 37227a8e76a3SSteven Rostedt } 3723c4f50183SRobert Richter EXPORT_SYMBOL_GPL(ring_buffer_peek); 37247a8e76a3SSteven Rostedt 3725f83c9d0fSSteven Rostedt static struct ring_buffer_event * 3726f83c9d0fSSteven Rostedt rb_iter_peek(struct ring_buffer_iter *iter, u64 *ts) 37277a8e76a3SSteven Rostedt { 37287a8e76a3SSteven Rostedt struct ring_buffer *buffer; 37297a8e76a3SSteven Rostedt struct ring_buffer_per_cpu *cpu_buffer; 37307a8e76a3SSteven Rostedt struct ring_buffer_event *event; 3731818e3dd3SSteven Rostedt int nr_loops = 0; 37327a8e76a3SSteven Rostedt 37337a8e76a3SSteven Rostedt cpu_buffer = iter->cpu_buffer; 37347a8e76a3SSteven Rostedt buffer = cpu_buffer->buffer; 37357a8e76a3SSteven Rostedt 3736492a74f4SSteven Rostedt /* 3737492a74f4SSteven Rostedt * Check if someone performed a consuming read to 3738492a74f4SSteven Rostedt * the buffer. A consuming read invalidates the iterator 3739492a74f4SSteven Rostedt * and we need to reset the iterator in this case. 3740492a74f4SSteven Rostedt */ 3741492a74f4SSteven Rostedt if (unlikely(iter->cache_read != cpu_buffer->read || 3742492a74f4SSteven Rostedt iter->cache_reader_page != cpu_buffer->reader_page)) 3743492a74f4SSteven Rostedt rb_iter_reset(iter); 3744492a74f4SSteven Rostedt 37457a8e76a3SSteven Rostedt again: 37463c05d748SSteven Rostedt if (ring_buffer_iter_empty(iter)) 37473c05d748SSteven Rostedt return NULL; 37483c05d748SSteven Rostedt 3749818e3dd3SSteven Rostedt /* 3750021de3d9SSteven Rostedt (Red Hat) * We repeat when a time extend is encountered or we hit 3751021de3d9SSteven Rostedt (Red Hat) * the end of the page. Since the time extend is always attached 3752021de3d9SSteven Rostedt (Red Hat) * to a data event, we should never loop more than three times. 3753021de3d9SSteven Rostedt (Red Hat) * Once for going to next page, once on time extend, and 3754021de3d9SSteven Rostedt (Red Hat) * finally once to get the event. 3755021de3d9SSteven Rostedt (Red Hat) * (We never hit the following condition more than thrice). 3756818e3dd3SSteven Rostedt */ 3757021de3d9SSteven Rostedt (Red Hat) if (RB_WARN_ON(cpu_buffer, ++nr_loops > 3)) 3758818e3dd3SSteven Rostedt return NULL; 3759818e3dd3SSteven Rostedt 37607a8e76a3SSteven Rostedt if (rb_per_cpu_empty(cpu_buffer)) 37617a8e76a3SSteven Rostedt return NULL; 37627a8e76a3SSteven Rostedt 376310e83fd0SSteven Rostedt (Red Hat) if (iter->head >= rb_page_size(iter->head_page)) { 37643c05d748SSteven Rostedt rb_inc_iter(iter); 37653c05d748SSteven Rostedt goto again; 37663c05d748SSteven Rostedt } 37673c05d748SSteven Rostedt 37687a8e76a3SSteven Rostedt event = rb_iter_head_event(iter); 37697a8e76a3SSteven Rostedt 3770334d4169SLai Jiangshan switch (event->type_len) { 37717a8e76a3SSteven Rostedt case RINGBUF_TYPE_PADDING: 37722d622719STom Zanussi if (rb_null_event(event)) { 3773d769041fSSteven Rostedt rb_inc_iter(iter); 37747a8e76a3SSteven Rostedt goto again; 37752d622719STom Zanussi } 37762d622719STom Zanussi rb_advance_iter(iter); 37772d622719STom Zanussi return event; 37787a8e76a3SSteven Rostedt 37797a8e76a3SSteven Rostedt case RINGBUF_TYPE_TIME_EXTEND: 37807a8e76a3SSteven Rostedt /* Internal data, OK to advance */ 37817a8e76a3SSteven Rostedt rb_advance_iter(iter); 37827a8e76a3SSteven Rostedt goto again; 37837a8e76a3SSteven Rostedt 37847a8e76a3SSteven Rostedt case RINGBUF_TYPE_TIME_STAMP: 37857a8e76a3SSteven Rostedt /* FIXME: not implemented */ 37867a8e76a3SSteven Rostedt rb_advance_iter(iter); 37877a8e76a3SSteven Rostedt goto again; 37887a8e76a3SSteven Rostedt 37897a8e76a3SSteven Rostedt case RINGBUF_TYPE_DATA: 37907a8e76a3SSteven Rostedt if (ts) { 37917a8e76a3SSteven Rostedt *ts = iter->read_stamp + event->time_delta; 379237886f6aSSteven Rostedt ring_buffer_normalize_time_stamp(buffer, 379337886f6aSSteven Rostedt cpu_buffer->cpu, ts); 37947a8e76a3SSteven Rostedt } 37957a8e76a3SSteven Rostedt return event; 37967a8e76a3SSteven Rostedt 37977a8e76a3SSteven Rostedt default: 37987a8e76a3SSteven Rostedt BUG(); 37997a8e76a3SSteven Rostedt } 38007a8e76a3SSteven Rostedt 38017a8e76a3SSteven Rostedt return NULL; 38027a8e76a3SSteven Rostedt } 3803c4f50183SRobert Richter EXPORT_SYMBOL_GPL(ring_buffer_iter_peek); 38047a8e76a3SSteven Rostedt 3805289a5a25SSteven Rostedt (Red Hat) static inline bool rb_reader_lock(struct ring_buffer_per_cpu *cpu_buffer) 38068d707e8eSSteven Rostedt { 3807289a5a25SSteven Rostedt (Red Hat) if (likely(!in_nmi())) { 3808289a5a25SSteven Rostedt (Red Hat) raw_spin_lock(&cpu_buffer->reader_lock); 3809289a5a25SSteven Rostedt (Red Hat) return true; 3810289a5a25SSteven Rostedt (Red Hat) } 3811289a5a25SSteven Rostedt (Red Hat) 38128d707e8eSSteven Rostedt /* 38138d707e8eSSteven Rostedt * If an NMI die dumps out the content of the ring buffer 3814289a5a25SSteven Rostedt (Red Hat) * trylock must be used to prevent a deadlock if the NMI 3815289a5a25SSteven Rostedt (Red Hat) * preempted a task that holds the ring buffer locks. If 3816289a5a25SSteven Rostedt (Red Hat) * we get the lock then all is fine, if not, then continue 3817289a5a25SSteven Rostedt (Red Hat) * to do the read, but this can corrupt the ring buffer, 3818289a5a25SSteven Rostedt (Red Hat) * so it must be permanently disabled from future writes. 3819289a5a25SSteven Rostedt (Red Hat) * Reading from NMI is a oneshot deal. 38208d707e8eSSteven Rostedt */ 3821289a5a25SSteven Rostedt (Red Hat) if (raw_spin_trylock(&cpu_buffer->reader_lock)) 3822289a5a25SSteven Rostedt (Red Hat) return true; 38238d707e8eSSteven Rostedt 3824289a5a25SSteven Rostedt (Red Hat) /* Continue without locking, but disable the ring buffer */ 3825289a5a25SSteven Rostedt (Red Hat) atomic_inc(&cpu_buffer->record_disabled); 3826289a5a25SSteven Rostedt (Red Hat) return false; 3827289a5a25SSteven Rostedt (Red Hat) } 3828289a5a25SSteven Rostedt (Red Hat) 3829289a5a25SSteven Rostedt (Red Hat) static inline void 3830289a5a25SSteven Rostedt (Red Hat) rb_reader_unlock(struct ring_buffer_per_cpu *cpu_buffer, bool locked) 3831289a5a25SSteven Rostedt (Red Hat) { 3832289a5a25SSteven Rostedt (Red Hat) if (likely(locked)) 3833289a5a25SSteven Rostedt (Red Hat) raw_spin_unlock(&cpu_buffer->reader_lock); 3834289a5a25SSteven Rostedt (Red Hat) return; 38358d707e8eSSteven Rostedt } 38368d707e8eSSteven Rostedt 38377a8e76a3SSteven Rostedt /** 3838f83c9d0fSSteven Rostedt * ring_buffer_peek - peek at the next event to be read 3839f83c9d0fSSteven Rostedt * @buffer: The ring buffer to read 3840f83c9d0fSSteven Rostedt * @cpu: The cpu to peak at 3841f83c9d0fSSteven Rostedt * @ts: The timestamp counter of this event. 384266a8cb95SSteven Rostedt * @lost_events: a variable to store if events were lost (may be NULL) 3843f83c9d0fSSteven Rostedt * 3844f83c9d0fSSteven Rostedt * This will return the event that will be read next, but does 3845f83c9d0fSSteven Rostedt * not consume the data. 3846f83c9d0fSSteven Rostedt */ 3847f83c9d0fSSteven Rostedt struct ring_buffer_event * 384866a8cb95SSteven Rostedt ring_buffer_peek(struct ring_buffer *buffer, int cpu, u64 *ts, 384966a8cb95SSteven Rostedt unsigned long *lost_events) 3850f83c9d0fSSteven Rostedt { 3851f83c9d0fSSteven Rostedt struct ring_buffer_per_cpu *cpu_buffer = buffer->buffers[cpu]; 38528aabee57SSteven Rostedt struct ring_buffer_event *event; 3853f83c9d0fSSteven Rostedt unsigned long flags; 3854289a5a25SSteven Rostedt (Red Hat) bool dolock; 3855f83c9d0fSSteven Rostedt 3856554f786eSSteven Rostedt if (!cpumask_test_cpu(cpu, buffer->cpumask)) 38578aabee57SSteven Rostedt return NULL; 3858554f786eSSteven Rostedt 38592d622719STom Zanussi again: 38608d707e8eSSteven Rostedt local_irq_save(flags); 3861289a5a25SSteven Rostedt (Red Hat) dolock = rb_reader_lock(cpu_buffer); 386266a8cb95SSteven Rostedt event = rb_buffer_peek(cpu_buffer, ts, lost_events); 3863469535a5SRobert Richter if (event && event->type_len == RINGBUF_TYPE_PADDING) 3864469535a5SRobert Richter rb_advance_reader(cpu_buffer); 3865289a5a25SSteven Rostedt (Red Hat) rb_reader_unlock(cpu_buffer, dolock); 38668d707e8eSSteven Rostedt local_irq_restore(flags); 3867f83c9d0fSSteven Rostedt 38681b959e18SSteven Rostedt if (event && event->type_len == RINGBUF_TYPE_PADDING) 38692d622719STom Zanussi goto again; 38702d622719STom Zanussi 3871f83c9d0fSSteven Rostedt return event; 3872f83c9d0fSSteven Rostedt } 3873f83c9d0fSSteven Rostedt 3874f83c9d0fSSteven Rostedt /** 3875f83c9d0fSSteven Rostedt * ring_buffer_iter_peek - peek at the next event to be read 3876f83c9d0fSSteven Rostedt * @iter: The ring buffer iterator 3877f83c9d0fSSteven Rostedt * @ts: The timestamp counter of this event. 3878f83c9d0fSSteven Rostedt * 3879f83c9d0fSSteven Rostedt * This will return the event that will be read next, but does 3880f83c9d0fSSteven Rostedt * not increment the iterator. 3881f83c9d0fSSteven Rostedt */ 3882f83c9d0fSSteven Rostedt struct ring_buffer_event * 3883f83c9d0fSSteven Rostedt ring_buffer_iter_peek(struct ring_buffer_iter *iter, u64 *ts) 3884f83c9d0fSSteven Rostedt { 3885f83c9d0fSSteven Rostedt struct ring_buffer_per_cpu *cpu_buffer = iter->cpu_buffer; 3886f83c9d0fSSteven Rostedt struct ring_buffer_event *event; 3887f83c9d0fSSteven Rostedt unsigned long flags; 3888f83c9d0fSSteven Rostedt 38892d622719STom Zanussi again: 38905389f6faSThomas Gleixner raw_spin_lock_irqsave(&cpu_buffer->reader_lock, flags); 3891f83c9d0fSSteven Rostedt event = rb_iter_peek(iter, ts); 38925389f6faSThomas Gleixner raw_spin_unlock_irqrestore(&cpu_buffer->reader_lock, flags); 3893f83c9d0fSSteven Rostedt 38941b959e18SSteven Rostedt if (event && event->type_len == RINGBUF_TYPE_PADDING) 38952d622719STom Zanussi goto again; 38962d622719STom Zanussi 3897f83c9d0fSSteven Rostedt return event; 3898f83c9d0fSSteven Rostedt } 3899f83c9d0fSSteven Rostedt 3900f83c9d0fSSteven Rostedt /** 39017a8e76a3SSteven Rostedt * ring_buffer_consume - return an event and consume it 39027a8e76a3SSteven Rostedt * @buffer: The ring buffer to get the next event from 390366a8cb95SSteven Rostedt * @cpu: the cpu to read the buffer from 390466a8cb95SSteven Rostedt * @ts: a variable to store the timestamp (may be NULL) 390566a8cb95SSteven Rostedt * @lost_events: a variable to store if events were lost (may be NULL) 39067a8e76a3SSteven Rostedt * 39077a8e76a3SSteven Rostedt * Returns the next event in the ring buffer, and that event is consumed. 39087a8e76a3SSteven Rostedt * Meaning, that sequential reads will keep returning a different event, 39097a8e76a3SSteven Rostedt * and eventually empty the ring buffer if the producer is slower. 39107a8e76a3SSteven Rostedt */ 39117a8e76a3SSteven Rostedt struct ring_buffer_event * 391266a8cb95SSteven Rostedt ring_buffer_consume(struct ring_buffer *buffer, int cpu, u64 *ts, 391366a8cb95SSteven Rostedt unsigned long *lost_events) 39147a8e76a3SSteven Rostedt { 3915554f786eSSteven Rostedt struct ring_buffer_per_cpu *cpu_buffer; 3916554f786eSSteven Rostedt struct ring_buffer_event *event = NULL; 3917f83c9d0fSSteven Rostedt unsigned long flags; 3918289a5a25SSteven Rostedt (Red Hat) bool dolock; 39197a8e76a3SSteven Rostedt 39202d622719STom Zanussi again: 3921554f786eSSteven Rostedt /* might be called in atomic */ 3922554f786eSSteven Rostedt preempt_disable(); 39237a8e76a3SSteven Rostedt 3924554f786eSSteven Rostedt if (!cpumask_test_cpu(cpu, buffer->cpumask)) 3925554f786eSSteven Rostedt goto out; 3926554f786eSSteven Rostedt 3927554f786eSSteven Rostedt cpu_buffer = buffer->buffers[cpu]; 39288d707e8eSSteven Rostedt local_irq_save(flags); 3929289a5a25SSteven Rostedt (Red Hat) dolock = rb_reader_lock(cpu_buffer); 39307a8e76a3SSteven Rostedt 393166a8cb95SSteven Rostedt event = rb_buffer_peek(cpu_buffer, ts, lost_events); 393266a8cb95SSteven Rostedt if (event) { 393366a8cb95SSteven Rostedt cpu_buffer->lost_events = 0; 3934d769041fSSteven Rostedt rb_advance_reader(cpu_buffer); 393566a8cb95SSteven Rostedt } 39367a8e76a3SSteven Rostedt 3937289a5a25SSteven Rostedt (Red Hat) rb_reader_unlock(cpu_buffer, dolock); 39388d707e8eSSteven Rostedt local_irq_restore(flags); 3939f83c9d0fSSteven Rostedt 3940554f786eSSteven Rostedt out: 3941554f786eSSteven Rostedt preempt_enable(); 3942554f786eSSteven Rostedt 39431b959e18SSteven Rostedt if (event && event->type_len == RINGBUF_TYPE_PADDING) 39442d622719STom Zanussi goto again; 39452d622719STom Zanussi 39467a8e76a3SSteven Rostedt return event; 39477a8e76a3SSteven Rostedt } 3948c4f50183SRobert Richter EXPORT_SYMBOL_GPL(ring_buffer_consume); 39497a8e76a3SSteven Rostedt 39507a8e76a3SSteven Rostedt /** 395172c9ddfdSDavid Miller * ring_buffer_read_prepare - Prepare for a non consuming read of the buffer 39527a8e76a3SSteven Rostedt * @buffer: The ring buffer to read from 39537a8e76a3SSteven Rostedt * @cpu: The cpu buffer to iterate over 39547a8e76a3SSteven Rostedt * 395572c9ddfdSDavid Miller * This performs the initial preparations necessary to iterate 395672c9ddfdSDavid Miller * through the buffer. Memory is allocated, buffer recording 395772c9ddfdSDavid Miller * is disabled, and the iterator pointer is returned to the caller. 39587a8e76a3SSteven Rostedt * 395972c9ddfdSDavid Miller * Disabling buffer recordng prevents the reading from being 396072c9ddfdSDavid Miller * corrupted. This is not a consuming read, so a producer is not 396172c9ddfdSDavid Miller * expected. 396272c9ddfdSDavid Miller * 396372c9ddfdSDavid Miller * After a sequence of ring_buffer_read_prepare calls, the user is 3964d611851bSzhangwei(Jovi) * expected to make at least one call to ring_buffer_read_prepare_sync. 396572c9ddfdSDavid Miller * Afterwards, ring_buffer_read_start is invoked to get things going 396672c9ddfdSDavid Miller * for real. 396772c9ddfdSDavid Miller * 3968d611851bSzhangwei(Jovi) * This overall must be paired with ring_buffer_read_finish. 39697a8e76a3SSteven Rostedt */ 39707a8e76a3SSteven Rostedt struct ring_buffer_iter * 397172c9ddfdSDavid Miller ring_buffer_read_prepare(struct ring_buffer *buffer, int cpu) 39727a8e76a3SSteven Rostedt { 39737a8e76a3SSteven Rostedt struct ring_buffer_per_cpu *cpu_buffer; 39748aabee57SSteven Rostedt struct ring_buffer_iter *iter; 39757a8e76a3SSteven Rostedt 39769e01c1b7SRusty Russell if (!cpumask_test_cpu(cpu, buffer->cpumask)) 39778aabee57SSteven Rostedt return NULL; 39787a8e76a3SSteven Rostedt 39797a8e76a3SSteven Rostedt iter = kmalloc(sizeof(*iter), GFP_KERNEL); 39807a8e76a3SSteven Rostedt if (!iter) 39818aabee57SSteven Rostedt return NULL; 39827a8e76a3SSteven Rostedt 39837a8e76a3SSteven Rostedt cpu_buffer = buffer->buffers[cpu]; 39847a8e76a3SSteven Rostedt 39857a8e76a3SSteven Rostedt iter->cpu_buffer = cpu_buffer; 39867a8e76a3SSteven Rostedt 398783f40318SVaibhav Nagarnaik atomic_inc(&buffer->resize_disabled); 39887a8e76a3SSteven Rostedt atomic_inc(&cpu_buffer->record_disabled); 398972c9ddfdSDavid Miller 399072c9ddfdSDavid Miller return iter; 399172c9ddfdSDavid Miller } 399272c9ddfdSDavid Miller EXPORT_SYMBOL_GPL(ring_buffer_read_prepare); 399372c9ddfdSDavid Miller 399472c9ddfdSDavid Miller /** 399572c9ddfdSDavid Miller * ring_buffer_read_prepare_sync - Synchronize a set of prepare calls 399672c9ddfdSDavid Miller * 399772c9ddfdSDavid Miller * All previously invoked ring_buffer_read_prepare calls to prepare 399872c9ddfdSDavid Miller * iterators will be synchronized. Afterwards, read_buffer_read_start 399972c9ddfdSDavid Miller * calls on those iterators are allowed. 400072c9ddfdSDavid Miller */ 400172c9ddfdSDavid Miller void 400272c9ddfdSDavid Miller ring_buffer_read_prepare_sync(void) 400372c9ddfdSDavid Miller { 40047a8e76a3SSteven Rostedt synchronize_sched(); 400572c9ddfdSDavid Miller } 400672c9ddfdSDavid Miller EXPORT_SYMBOL_GPL(ring_buffer_read_prepare_sync); 400772c9ddfdSDavid Miller 400872c9ddfdSDavid Miller /** 400972c9ddfdSDavid Miller * ring_buffer_read_start - start a non consuming read of the buffer 401072c9ddfdSDavid Miller * @iter: The iterator returned by ring_buffer_read_prepare 401172c9ddfdSDavid Miller * 401272c9ddfdSDavid Miller * This finalizes the startup of an iteration through the buffer. 401372c9ddfdSDavid Miller * The iterator comes from a call to ring_buffer_read_prepare and 401472c9ddfdSDavid Miller * an intervening ring_buffer_read_prepare_sync must have been 401572c9ddfdSDavid Miller * performed. 401672c9ddfdSDavid Miller * 4017d611851bSzhangwei(Jovi) * Must be paired with ring_buffer_read_finish. 401872c9ddfdSDavid Miller */ 401972c9ddfdSDavid Miller void 402072c9ddfdSDavid Miller ring_buffer_read_start(struct ring_buffer_iter *iter) 402172c9ddfdSDavid Miller { 402272c9ddfdSDavid Miller struct ring_buffer_per_cpu *cpu_buffer; 402372c9ddfdSDavid Miller unsigned long flags; 402472c9ddfdSDavid Miller 402572c9ddfdSDavid Miller if (!iter) 402672c9ddfdSDavid Miller return; 402772c9ddfdSDavid Miller 402872c9ddfdSDavid Miller cpu_buffer = iter->cpu_buffer; 40297a8e76a3SSteven Rostedt 40305389f6faSThomas Gleixner raw_spin_lock_irqsave(&cpu_buffer->reader_lock, flags); 40310199c4e6SThomas Gleixner arch_spin_lock(&cpu_buffer->lock); 4032642edba5SSteven Rostedt rb_iter_reset(iter); 40330199c4e6SThomas Gleixner arch_spin_unlock(&cpu_buffer->lock); 40345389f6faSThomas Gleixner raw_spin_unlock_irqrestore(&cpu_buffer->reader_lock, flags); 40357a8e76a3SSteven Rostedt } 4036c4f50183SRobert Richter EXPORT_SYMBOL_GPL(ring_buffer_read_start); 40377a8e76a3SSteven Rostedt 40387a8e76a3SSteven Rostedt /** 4039d611851bSzhangwei(Jovi) * ring_buffer_read_finish - finish reading the iterator of the buffer 40407a8e76a3SSteven Rostedt * @iter: The iterator retrieved by ring_buffer_start 40417a8e76a3SSteven Rostedt * 40427a8e76a3SSteven Rostedt * This re-enables the recording to the buffer, and frees the 40437a8e76a3SSteven Rostedt * iterator. 40447a8e76a3SSteven Rostedt */ 40457a8e76a3SSteven Rostedt void 40467a8e76a3SSteven Rostedt ring_buffer_read_finish(struct ring_buffer_iter *iter) 40477a8e76a3SSteven Rostedt { 40487a8e76a3SSteven Rostedt struct ring_buffer_per_cpu *cpu_buffer = iter->cpu_buffer; 40499366c1baSSteven Rostedt unsigned long flags; 40507a8e76a3SSteven Rostedt 4051659f451fSSteven Rostedt /* 4052659f451fSSteven Rostedt * Ring buffer is disabled from recording, here's a good place 4053659f451fSSteven Rostedt * to check the integrity of the ring buffer. 40549366c1baSSteven Rostedt * Must prevent readers from trying to read, as the check 40559366c1baSSteven Rostedt * clears the HEAD page and readers require it. 4056659f451fSSteven Rostedt */ 40579366c1baSSteven Rostedt raw_spin_lock_irqsave(&cpu_buffer->reader_lock, flags); 4058659f451fSSteven Rostedt rb_check_pages(cpu_buffer); 40599366c1baSSteven Rostedt raw_spin_unlock_irqrestore(&cpu_buffer->reader_lock, flags); 4060659f451fSSteven Rostedt 40617a8e76a3SSteven Rostedt atomic_dec(&cpu_buffer->record_disabled); 406283f40318SVaibhav Nagarnaik atomic_dec(&cpu_buffer->buffer->resize_disabled); 40637a8e76a3SSteven Rostedt kfree(iter); 40647a8e76a3SSteven Rostedt } 4065c4f50183SRobert Richter EXPORT_SYMBOL_GPL(ring_buffer_read_finish); 40667a8e76a3SSteven Rostedt 40677a8e76a3SSteven Rostedt /** 40687a8e76a3SSteven Rostedt * ring_buffer_read - read the next item in the ring buffer by the iterator 40697a8e76a3SSteven Rostedt * @iter: The ring buffer iterator 40707a8e76a3SSteven Rostedt * @ts: The time stamp of the event read. 40717a8e76a3SSteven Rostedt * 40727a8e76a3SSteven Rostedt * This reads the next event in the ring buffer and increments the iterator. 40737a8e76a3SSteven Rostedt */ 40747a8e76a3SSteven Rostedt struct ring_buffer_event * 40757a8e76a3SSteven Rostedt ring_buffer_read(struct ring_buffer_iter *iter, u64 *ts) 40767a8e76a3SSteven Rostedt { 40777a8e76a3SSteven Rostedt struct ring_buffer_event *event; 4078f83c9d0fSSteven Rostedt struct ring_buffer_per_cpu *cpu_buffer = iter->cpu_buffer; 4079f83c9d0fSSteven Rostedt unsigned long flags; 40807a8e76a3SSteven Rostedt 40815389f6faSThomas Gleixner raw_spin_lock_irqsave(&cpu_buffer->reader_lock, flags); 40827e9391cfSSteven Rostedt again: 4083f83c9d0fSSteven Rostedt event = rb_iter_peek(iter, ts); 40847a8e76a3SSteven Rostedt if (!event) 4085f83c9d0fSSteven Rostedt goto out; 40867a8e76a3SSteven Rostedt 40877e9391cfSSteven Rostedt if (event->type_len == RINGBUF_TYPE_PADDING) 40887e9391cfSSteven Rostedt goto again; 40897e9391cfSSteven Rostedt 40907a8e76a3SSteven Rostedt rb_advance_iter(iter); 4091f83c9d0fSSteven Rostedt out: 40925389f6faSThomas Gleixner raw_spin_unlock_irqrestore(&cpu_buffer->reader_lock, flags); 40937a8e76a3SSteven Rostedt 40947a8e76a3SSteven Rostedt return event; 40957a8e76a3SSteven Rostedt } 4096c4f50183SRobert Richter EXPORT_SYMBOL_GPL(ring_buffer_read); 40977a8e76a3SSteven Rostedt 40987a8e76a3SSteven Rostedt /** 40997a8e76a3SSteven Rostedt * ring_buffer_size - return the size of the ring buffer (in bytes) 41007a8e76a3SSteven Rostedt * @buffer: The ring buffer. 41017a8e76a3SSteven Rostedt */ 4102438ced17SVaibhav Nagarnaik unsigned long ring_buffer_size(struct ring_buffer *buffer, int cpu) 41037a8e76a3SSteven Rostedt { 4104438ced17SVaibhav Nagarnaik /* 4105438ced17SVaibhav Nagarnaik * Earlier, this method returned 4106438ced17SVaibhav Nagarnaik * BUF_PAGE_SIZE * buffer->nr_pages 4107438ced17SVaibhav Nagarnaik * Since the nr_pages field is now removed, we have converted this to 4108438ced17SVaibhav Nagarnaik * return the per cpu buffer value. 4109438ced17SVaibhav Nagarnaik */ 4110438ced17SVaibhav Nagarnaik if (!cpumask_test_cpu(cpu, buffer->cpumask)) 4111438ced17SVaibhav Nagarnaik return 0; 4112438ced17SVaibhav Nagarnaik 4113438ced17SVaibhav Nagarnaik return BUF_PAGE_SIZE * buffer->buffers[cpu]->nr_pages; 41147a8e76a3SSteven Rostedt } 4115c4f50183SRobert Richter EXPORT_SYMBOL_GPL(ring_buffer_size); 41167a8e76a3SSteven Rostedt 41177a8e76a3SSteven Rostedt static void 41187a8e76a3SSteven Rostedt rb_reset_cpu(struct ring_buffer_per_cpu *cpu_buffer) 41197a8e76a3SSteven Rostedt { 412077ae365eSSteven Rostedt rb_head_page_deactivate(cpu_buffer); 412177ae365eSSteven Rostedt 41227a8e76a3SSteven Rostedt cpu_buffer->head_page 41233adc54faSSteven Rostedt = list_entry(cpu_buffer->pages, struct buffer_page, list); 4124bf41a158SSteven Rostedt local_set(&cpu_buffer->head_page->write, 0); 4125778c55d4SSteven Rostedt local_set(&cpu_buffer->head_page->entries, 0); 4126abc9b56dSSteven Rostedt local_set(&cpu_buffer->head_page->page->commit, 0); 41277a8e76a3SSteven Rostedt 41286f807acdSSteven Rostedt cpu_buffer->head_page->read = 0; 4129bf41a158SSteven Rostedt 4130bf41a158SSteven Rostedt cpu_buffer->tail_page = cpu_buffer->head_page; 4131bf41a158SSteven Rostedt cpu_buffer->commit_page = cpu_buffer->head_page; 4132bf41a158SSteven Rostedt 4133bf41a158SSteven Rostedt INIT_LIST_HEAD(&cpu_buffer->reader_page->list); 41345040b4b7SVaibhav Nagarnaik INIT_LIST_HEAD(&cpu_buffer->new_pages); 4135bf41a158SSteven Rostedt local_set(&cpu_buffer->reader_page->write, 0); 4136778c55d4SSteven Rostedt local_set(&cpu_buffer->reader_page->entries, 0); 4137abc9b56dSSteven Rostedt local_set(&cpu_buffer->reader_page->page->commit, 0); 41386f807acdSSteven Rostedt cpu_buffer->reader_page->read = 0; 4139d769041fSSteven Rostedt 4140c64e148aSVaibhav Nagarnaik local_set(&cpu_buffer->entries_bytes, 0); 414177ae365eSSteven Rostedt local_set(&cpu_buffer->overrun, 0); 4142884bfe89SSlava Pestov local_set(&cpu_buffer->commit_overrun, 0); 4143884bfe89SSlava Pestov local_set(&cpu_buffer->dropped_events, 0); 4144e4906effSSteven Rostedt local_set(&cpu_buffer->entries, 0); 4145fa743953SSteven Rostedt local_set(&cpu_buffer->committing, 0); 4146fa743953SSteven Rostedt local_set(&cpu_buffer->commits, 0); 414777ae365eSSteven Rostedt cpu_buffer->read = 0; 4148c64e148aSVaibhav Nagarnaik cpu_buffer->read_bytes = 0; 414969507c06SSteven Rostedt 415069507c06SSteven Rostedt cpu_buffer->write_stamp = 0; 415169507c06SSteven Rostedt cpu_buffer->read_stamp = 0; 415277ae365eSSteven Rostedt 415366a8cb95SSteven Rostedt cpu_buffer->lost_events = 0; 415466a8cb95SSteven Rostedt cpu_buffer->last_overrun = 0; 415566a8cb95SSteven Rostedt 415677ae365eSSteven Rostedt rb_head_page_activate(cpu_buffer); 41577a8e76a3SSteven Rostedt } 41587a8e76a3SSteven Rostedt 41597a8e76a3SSteven Rostedt /** 41607a8e76a3SSteven Rostedt * ring_buffer_reset_cpu - reset a ring buffer per CPU buffer 41617a8e76a3SSteven Rostedt * @buffer: The ring buffer to reset a per cpu buffer of 41627a8e76a3SSteven Rostedt * @cpu: The CPU buffer to be reset 41637a8e76a3SSteven Rostedt */ 41647a8e76a3SSteven Rostedt void ring_buffer_reset_cpu(struct ring_buffer *buffer, int cpu) 41657a8e76a3SSteven Rostedt { 41667a8e76a3SSteven Rostedt struct ring_buffer_per_cpu *cpu_buffer = buffer->buffers[cpu]; 41677a8e76a3SSteven Rostedt unsigned long flags; 41687a8e76a3SSteven Rostedt 41699e01c1b7SRusty Russell if (!cpumask_test_cpu(cpu, buffer->cpumask)) 41708aabee57SSteven Rostedt return; 41717a8e76a3SSteven Rostedt 417283f40318SVaibhav Nagarnaik atomic_inc(&buffer->resize_disabled); 417341ede23eSSteven Rostedt atomic_inc(&cpu_buffer->record_disabled); 417441ede23eSSteven Rostedt 417583f40318SVaibhav Nagarnaik /* Make sure all commits have finished */ 417683f40318SVaibhav Nagarnaik synchronize_sched(); 417783f40318SVaibhav Nagarnaik 41785389f6faSThomas Gleixner raw_spin_lock_irqsave(&cpu_buffer->reader_lock, flags); 4179f83c9d0fSSteven Rostedt 418041b6a95dSSteven Rostedt if (RB_WARN_ON(cpu_buffer, local_read(&cpu_buffer->committing))) 418141b6a95dSSteven Rostedt goto out; 418241b6a95dSSteven Rostedt 41830199c4e6SThomas Gleixner arch_spin_lock(&cpu_buffer->lock); 41847a8e76a3SSteven Rostedt 41857a8e76a3SSteven Rostedt rb_reset_cpu(cpu_buffer); 41867a8e76a3SSteven Rostedt 41870199c4e6SThomas Gleixner arch_spin_unlock(&cpu_buffer->lock); 4188f83c9d0fSSteven Rostedt 418941b6a95dSSteven Rostedt out: 41905389f6faSThomas Gleixner raw_spin_unlock_irqrestore(&cpu_buffer->reader_lock, flags); 419141ede23eSSteven Rostedt 419241ede23eSSteven Rostedt atomic_dec(&cpu_buffer->record_disabled); 419383f40318SVaibhav Nagarnaik atomic_dec(&buffer->resize_disabled); 41947a8e76a3SSteven Rostedt } 4195c4f50183SRobert Richter EXPORT_SYMBOL_GPL(ring_buffer_reset_cpu); 41967a8e76a3SSteven Rostedt 41977a8e76a3SSteven Rostedt /** 41987a8e76a3SSteven Rostedt * ring_buffer_reset - reset a ring buffer 41997a8e76a3SSteven Rostedt * @buffer: The ring buffer to reset all cpu buffers 42007a8e76a3SSteven Rostedt */ 42017a8e76a3SSteven Rostedt void ring_buffer_reset(struct ring_buffer *buffer) 42027a8e76a3SSteven Rostedt { 42037a8e76a3SSteven Rostedt int cpu; 42047a8e76a3SSteven Rostedt 42057a8e76a3SSteven Rostedt for_each_buffer_cpu(buffer, cpu) 4206d769041fSSteven Rostedt ring_buffer_reset_cpu(buffer, cpu); 42077a8e76a3SSteven Rostedt } 4208c4f50183SRobert Richter EXPORT_SYMBOL_GPL(ring_buffer_reset); 42097a8e76a3SSteven Rostedt 42107a8e76a3SSteven Rostedt /** 42117a8e76a3SSteven Rostedt * rind_buffer_empty - is the ring buffer empty? 42127a8e76a3SSteven Rostedt * @buffer: The ring buffer to test 42137a8e76a3SSteven Rostedt */ 42143d4e204dSYaowei Bai bool ring_buffer_empty(struct ring_buffer *buffer) 42157a8e76a3SSteven Rostedt { 42167a8e76a3SSteven Rostedt struct ring_buffer_per_cpu *cpu_buffer; 4217d4788207SSteven Rostedt unsigned long flags; 4218289a5a25SSteven Rostedt (Red Hat) bool dolock; 42197a8e76a3SSteven Rostedt int cpu; 4220d4788207SSteven Rostedt int ret; 42217a8e76a3SSteven Rostedt 42227a8e76a3SSteven Rostedt /* yes this is racy, but if you don't like the race, lock the buffer */ 42237a8e76a3SSteven Rostedt for_each_buffer_cpu(buffer, cpu) { 42247a8e76a3SSteven Rostedt cpu_buffer = buffer->buffers[cpu]; 42258d707e8eSSteven Rostedt local_irq_save(flags); 4226289a5a25SSteven Rostedt (Red Hat) dolock = rb_reader_lock(cpu_buffer); 4227d4788207SSteven Rostedt ret = rb_per_cpu_empty(cpu_buffer); 4228289a5a25SSteven Rostedt (Red Hat) rb_reader_unlock(cpu_buffer, dolock); 42298d707e8eSSteven Rostedt local_irq_restore(flags); 42308d707e8eSSteven Rostedt 4231d4788207SSteven Rostedt if (!ret) 42323d4e204dSYaowei Bai return false; 42337a8e76a3SSteven Rostedt } 4234554f786eSSteven Rostedt 42353d4e204dSYaowei Bai return true; 42367a8e76a3SSteven Rostedt } 4237c4f50183SRobert Richter EXPORT_SYMBOL_GPL(ring_buffer_empty); 42387a8e76a3SSteven Rostedt 42397a8e76a3SSteven Rostedt /** 42407a8e76a3SSteven Rostedt * ring_buffer_empty_cpu - is a cpu buffer of a ring buffer empty? 42417a8e76a3SSteven Rostedt * @buffer: The ring buffer 42427a8e76a3SSteven Rostedt * @cpu: The CPU buffer to test 42437a8e76a3SSteven Rostedt */ 42443d4e204dSYaowei Bai bool ring_buffer_empty_cpu(struct ring_buffer *buffer, int cpu) 42457a8e76a3SSteven Rostedt { 42467a8e76a3SSteven Rostedt struct ring_buffer_per_cpu *cpu_buffer; 4247d4788207SSteven Rostedt unsigned long flags; 4248289a5a25SSteven Rostedt (Red Hat) bool dolock; 42498aabee57SSteven Rostedt int ret; 42507a8e76a3SSteven Rostedt 42519e01c1b7SRusty Russell if (!cpumask_test_cpu(cpu, buffer->cpumask)) 42523d4e204dSYaowei Bai return true; 42537a8e76a3SSteven Rostedt 42547a8e76a3SSteven Rostedt cpu_buffer = buffer->buffers[cpu]; 42558d707e8eSSteven Rostedt local_irq_save(flags); 4256289a5a25SSteven Rostedt (Red Hat) dolock = rb_reader_lock(cpu_buffer); 4257554f786eSSteven Rostedt ret = rb_per_cpu_empty(cpu_buffer); 4258289a5a25SSteven Rostedt (Red Hat) rb_reader_unlock(cpu_buffer, dolock); 42598d707e8eSSteven Rostedt local_irq_restore(flags); 4260554f786eSSteven Rostedt 4261554f786eSSteven Rostedt return ret; 42627a8e76a3SSteven Rostedt } 4263c4f50183SRobert Richter EXPORT_SYMBOL_GPL(ring_buffer_empty_cpu); 42647a8e76a3SSteven Rostedt 426585bac32cSSteven Rostedt #ifdef CONFIG_RING_BUFFER_ALLOW_SWAP 42667a8e76a3SSteven Rostedt /** 42677a8e76a3SSteven Rostedt * ring_buffer_swap_cpu - swap a CPU buffer between two ring buffers 42687a8e76a3SSteven Rostedt * @buffer_a: One buffer to swap with 42697a8e76a3SSteven Rostedt * @buffer_b: The other buffer to swap with 42707a8e76a3SSteven Rostedt * 42717a8e76a3SSteven Rostedt * This function is useful for tracers that want to take a "snapshot" 42727a8e76a3SSteven Rostedt * of a CPU buffer and has another back up buffer lying around. 42737a8e76a3SSteven Rostedt * it is expected that the tracer handles the cpu buffer not being 42747a8e76a3SSteven Rostedt * used at the moment. 42757a8e76a3SSteven Rostedt */ 42767a8e76a3SSteven Rostedt int ring_buffer_swap_cpu(struct ring_buffer *buffer_a, 42777a8e76a3SSteven Rostedt struct ring_buffer *buffer_b, int cpu) 42787a8e76a3SSteven Rostedt { 42797a8e76a3SSteven Rostedt struct ring_buffer_per_cpu *cpu_buffer_a; 42807a8e76a3SSteven Rostedt struct ring_buffer_per_cpu *cpu_buffer_b; 4281554f786eSSteven Rostedt int ret = -EINVAL; 4282554f786eSSteven Rostedt 42839e01c1b7SRusty Russell if (!cpumask_test_cpu(cpu, buffer_a->cpumask) || 42849e01c1b7SRusty Russell !cpumask_test_cpu(cpu, buffer_b->cpumask)) 4285554f786eSSteven Rostedt goto out; 42867a8e76a3SSteven Rostedt 4287438ced17SVaibhav Nagarnaik cpu_buffer_a = buffer_a->buffers[cpu]; 4288438ced17SVaibhav Nagarnaik cpu_buffer_b = buffer_b->buffers[cpu]; 4289438ced17SVaibhav Nagarnaik 42907a8e76a3SSteven Rostedt /* At least make sure the two buffers are somewhat the same */ 4291438ced17SVaibhav Nagarnaik if (cpu_buffer_a->nr_pages != cpu_buffer_b->nr_pages) 4292554f786eSSteven Rostedt goto out; 4293554f786eSSteven Rostedt 4294554f786eSSteven Rostedt ret = -EAGAIN; 42957a8e76a3SSteven Rostedt 429697b17efeSSteven Rostedt if (atomic_read(&buffer_a->record_disabled)) 4297554f786eSSteven Rostedt goto out; 429897b17efeSSteven Rostedt 429997b17efeSSteven Rostedt if (atomic_read(&buffer_b->record_disabled)) 4300554f786eSSteven Rostedt goto out; 430197b17efeSSteven Rostedt 430297b17efeSSteven Rostedt if (atomic_read(&cpu_buffer_a->record_disabled)) 4303554f786eSSteven Rostedt goto out; 430497b17efeSSteven Rostedt 430597b17efeSSteven Rostedt if (atomic_read(&cpu_buffer_b->record_disabled)) 4306554f786eSSteven Rostedt goto out; 430797b17efeSSteven Rostedt 43087a8e76a3SSteven Rostedt /* 43097a8e76a3SSteven Rostedt * We can't do a synchronize_sched here because this 43107a8e76a3SSteven Rostedt * function can be called in atomic context. 43117a8e76a3SSteven Rostedt * Normally this will be called from the same CPU as cpu. 43127a8e76a3SSteven Rostedt * If not it's up to the caller to protect this. 43137a8e76a3SSteven Rostedt */ 43147a8e76a3SSteven Rostedt atomic_inc(&cpu_buffer_a->record_disabled); 43157a8e76a3SSteven Rostedt atomic_inc(&cpu_buffer_b->record_disabled); 43167a8e76a3SSteven Rostedt 431798277991SSteven Rostedt ret = -EBUSY; 431898277991SSteven Rostedt if (local_read(&cpu_buffer_a->committing)) 431998277991SSteven Rostedt goto out_dec; 432098277991SSteven Rostedt if (local_read(&cpu_buffer_b->committing)) 432198277991SSteven Rostedt goto out_dec; 432298277991SSteven Rostedt 43237a8e76a3SSteven Rostedt buffer_a->buffers[cpu] = cpu_buffer_b; 43247a8e76a3SSteven Rostedt buffer_b->buffers[cpu] = cpu_buffer_a; 43257a8e76a3SSteven Rostedt 43267a8e76a3SSteven Rostedt cpu_buffer_b->buffer = buffer_a; 43277a8e76a3SSteven Rostedt cpu_buffer_a->buffer = buffer_b; 43287a8e76a3SSteven Rostedt 432998277991SSteven Rostedt ret = 0; 433098277991SSteven Rostedt 433198277991SSteven Rostedt out_dec: 43327a8e76a3SSteven Rostedt atomic_dec(&cpu_buffer_a->record_disabled); 43337a8e76a3SSteven Rostedt atomic_dec(&cpu_buffer_b->record_disabled); 4334554f786eSSteven Rostedt out: 4335554f786eSSteven Rostedt return ret; 43367a8e76a3SSteven Rostedt } 4337c4f50183SRobert Richter EXPORT_SYMBOL_GPL(ring_buffer_swap_cpu); 433885bac32cSSteven Rostedt #endif /* CONFIG_RING_BUFFER_ALLOW_SWAP */ 43397a8e76a3SSteven Rostedt 43408789a9e7SSteven Rostedt /** 43418789a9e7SSteven Rostedt * ring_buffer_alloc_read_page - allocate a page to read from buffer 43428789a9e7SSteven Rostedt * @buffer: the buffer to allocate for. 4343d611851bSzhangwei(Jovi) * @cpu: the cpu buffer to allocate. 43448789a9e7SSteven Rostedt * 43458789a9e7SSteven Rostedt * This function is used in conjunction with ring_buffer_read_page. 43468789a9e7SSteven Rostedt * When reading a full page from the ring buffer, these functions 43478789a9e7SSteven Rostedt * can be used to speed up the process. The calling function should 43488789a9e7SSteven Rostedt * allocate a few pages first with this function. Then when it 43498789a9e7SSteven Rostedt * needs to get pages from the ring buffer, it passes the result 43508789a9e7SSteven Rostedt * of this function into ring_buffer_read_page, which will swap 43518789a9e7SSteven Rostedt * the page that was allocated, with the read page of the buffer. 43528789a9e7SSteven Rostedt * 43538789a9e7SSteven Rostedt * Returns: 4354a7e52ad7SSteven Rostedt (VMware) * The page allocated, or ERR_PTR 43558789a9e7SSteven Rostedt */ 43567ea59064SVaibhav Nagarnaik void *ring_buffer_alloc_read_page(struct ring_buffer *buffer, int cpu) 43578789a9e7SSteven Rostedt { 4358a7e52ad7SSteven Rostedt (VMware) struct ring_buffer_per_cpu *cpu_buffer; 435973a757e6SSteven Rostedt (VMware) struct buffer_data_page *bpage = NULL; 436073a757e6SSteven Rostedt (VMware) unsigned long flags; 43617ea59064SVaibhav Nagarnaik struct page *page; 43628789a9e7SSteven Rostedt 4363a7e52ad7SSteven Rostedt (VMware) if (!cpumask_test_cpu(cpu, buffer->cpumask)) 4364a7e52ad7SSteven Rostedt (VMware) return ERR_PTR(-ENODEV); 4365a7e52ad7SSteven Rostedt (VMware) 4366a7e52ad7SSteven Rostedt (VMware) cpu_buffer = buffer->buffers[cpu]; 436773a757e6SSteven Rostedt (VMware) local_irq_save(flags); 436873a757e6SSteven Rostedt (VMware) arch_spin_lock(&cpu_buffer->lock); 436973a757e6SSteven Rostedt (VMware) 437073a757e6SSteven Rostedt (VMware) if (cpu_buffer->free_page) { 437173a757e6SSteven Rostedt (VMware) bpage = cpu_buffer->free_page; 437273a757e6SSteven Rostedt (VMware) cpu_buffer->free_page = NULL; 437373a757e6SSteven Rostedt (VMware) } 437473a757e6SSteven Rostedt (VMware) 437573a757e6SSteven Rostedt (VMware) arch_spin_unlock(&cpu_buffer->lock); 437673a757e6SSteven Rostedt (VMware) local_irq_restore(flags); 437773a757e6SSteven Rostedt (VMware) 437873a757e6SSteven Rostedt (VMware) if (bpage) 437973a757e6SSteven Rostedt (VMware) goto out; 438073a757e6SSteven Rostedt (VMware) 4381d7ec4bfeSVaibhav Nagarnaik page = alloc_pages_node(cpu_to_node(cpu), 4382d7ec4bfeSVaibhav Nagarnaik GFP_KERNEL | __GFP_NORETRY, 0); 43837ea59064SVaibhav Nagarnaik if (!page) 4384a7e52ad7SSteven Rostedt (VMware) return ERR_PTR(-ENOMEM); 43858789a9e7SSteven Rostedt 43867ea59064SVaibhav Nagarnaik bpage = page_address(page); 43878789a9e7SSteven Rostedt 438873a757e6SSteven Rostedt (VMware) out: 4389ef7a4a16SSteven Rostedt rb_init_page(bpage); 4390ef7a4a16SSteven Rostedt 4391044fa782SSteven Rostedt return bpage; 43928789a9e7SSteven Rostedt } 4393d6ce96daSSteven Rostedt EXPORT_SYMBOL_GPL(ring_buffer_alloc_read_page); 43948789a9e7SSteven Rostedt 43958789a9e7SSteven Rostedt /** 43968789a9e7SSteven Rostedt * ring_buffer_free_read_page - free an allocated read page 43978789a9e7SSteven Rostedt * @buffer: the buffer the page was allocate for 439873a757e6SSteven Rostedt (VMware) * @cpu: the cpu buffer the page came from 43998789a9e7SSteven Rostedt * @data: the page to free 44008789a9e7SSteven Rostedt * 44018789a9e7SSteven Rostedt * Free a page allocated from ring_buffer_alloc_read_page. 44028789a9e7SSteven Rostedt */ 440373a757e6SSteven Rostedt (VMware) void ring_buffer_free_read_page(struct ring_buffer *buffer, int cpu, void *data) 44048789a9e7SSteven Rostedt { 440573a757e6SSteven Rostedt (VMware) struct ring_buffer_per_cpu *cpu_buffer = buffer->buffers[cpu]; 440673a757e6SSteven Rostedt (VMware) struct buffer_data_page *bpage = data; 4407*ae415fa4SSteven Rostedt (VMware) struct page *page = virt_to_page(bpage); 440873a757e6SSteven Rostedt (VMware) unsigned long flags; 440973a757e6SSteven Rostedt (VMware) 4410*ae415fa4SSteven Rostedt (VMware) /* If the page is still in use someplace else, we can't reuse it */ 4411*ae415fa4SSteven Rostedt (VMware) if (page_ref_count(page) > 1) 4412*ae415fa4SSteven Rostedt (VMware) goto out; 4413*ae415fa4SSteven Rostedt (VMware) 441473a757e6SSteven Rostedt (VMware) local_irq_save(flags); 441573a757e6SSteven Rostedt (VMware) arch_spin_lock(&cpu_buffer->lock); 441673a757e6SSteven Rostedt (VMware) 441773a757e6SSteven Rostedt (VMware) if (!cpu_buffer->free_page) { 441873a757e6SSteven Rostedt (VMware) cpu_buffer->free_page = bpage; 441973a757e6SSteven Rostedt (VMware) bpage = NULL; 442073a757e6SSteven Rostedt (VMware) } 442173a757e6SSteven Rostedt (VMware) 442273a757e6SSteven Rostedt (VMware) arch_spin_unlock(&cpu_buffer->lock); 442373a757e6SSteven Rostedt (VMware) local_irq_restore(flags); 442473a757e6SSteven Rostedt (VMware) 4425*ae415fa4SSteven Rostedt (VMware) out: 442673a757e6SSteven Rostedt (VMware) free_page((unsigned long)bpage); 44278789a9e7SSteven Rostedt } 4428d6ce96daSSteven Rostedt EXPORT_SYMBOL_GPL(ring_buffer_free_read_page); 44298789a9e7SSteven Rostedt 44308789a9e7SSteven Rostedt /** 44318789a9e7SSteven Rostedt * ring_buffer_read_page - extract a page from the ring buffer 44328789a9e7SSteven Rostedt * @buffer: buffer to extract from 44338789a9e7SSteven Rostedt * @data_page: the page to use allocated from ring_buffer_alloc_read_page 4434ef7a4a16SSteven Rostedt * @len: amount to extract 44358789a9e7SSteven Rostedt * @cpu: the cpu of the buffer to extract 44368789a9e7SSteven Rostedt * @full: should the extraction only happen when the page is full. 44378789a9e7SSteven Rostedt * 44388789a9e7SSteven Rostedt * This function will pull out a page from the ring buffer and consume it. 44398789a9e7SSteven Rostedt * @data_page must be the address of the variable that was returned 44408789a9e7SSteven Rostedt * from ring_buffer_alloc_read_page. This is because the page might be used 44418789a9e7SSteven Rostedt * to swap with a page in the ring buffer. 44428789a9e7SSteven Rostedt * 44438789a9e7SSteven Rostedt * for example: 4444d611851bSzhangwei(Jovi) * rpage = ring_buffer_alloc_read_page(buffer, cpu); 4445a7e52ad7SSteven Rostedt (VMware) * if (IS_ERR(rpage)) 4446a7e52ad7SSteven Rostedt (VMware) * return PTR_ERR(rpage); 4447ef7a4a16SSteven Rostedt * ret = ring_buffer_read_page(buffer, &rpage, len, cpu, 0); 4448667d2412SLai Jiangshan * if (ret >= 0) 4449667d2412SLai Jiangshan * process_page(rpage, ret); 44508789a9e7SSteven Rostedt * 44518789a9e7SSteven Rostedt * When @full is set, the function will not return true unless 44528789a9e7SSteven Rostedt * the writer is off the reader page. 44538789a9e7SSteven Rostedt * 44548789a9e7SSteven Rostedt * Note: it is up to the calling functions to handle sleeps and wakeups. 44558789a9e7SSteven Rostedt * The ring buffer can be used anywhere in the kernel and can not 44568789a9e7SSteven Rostedt * blindly call wake_up. The layer that uses the ring buffer must be 44578789a9e7SSteven Rostedt * responsible for that. 44588789a9e7SSteven Rostedt * 44598789a9e7SSteven Rostedt * Returns: 4460667d2412SLai Jiangshan * >=0 if data has been transferred, returns the offset of consumed data. 4461667d2412SLai Jiangshan * <0 if no data has been transferred. 44628789a9e7SSteven Rostedt */ 44638789a9e7SSteven Rostedt int ring_buffer_read_page(struct ring_buffer *buffer, 4464ef7a4a16SSteven Rostedt void **data_page, size_t len, int cpu, int full) 44658789a9e7SSteven Rostedt { 44668789a9e7SSteven Rostedt struct ring_buffer_per_cpu *cpu_buffer = buffer->buffers[cpu]; 44678789a9e7SSteven Rostedt struct ring_buffer_event *event; 4468044fa782SSteven Rostedt struct buffer_data_page *bpage; 4469ef7a4a16SSteven Rostedt struct buffer_page *reader; 4470ff0ff84aSSteven Rostedt unsigned long missed_events; 44718789a9e7SSteven Rostedt unsigned long flags; 4472ef7a4a16SSteven Rostedt unsigned int commit; 4473667d2412SLai Jiangshan unsigned int read; 44744f3640f8SSteven Rostedt u64 save_timestamp; 4475667d2412SLai Jiangshan int ret = -1; 44768789a9e7SSteven Rostedt 4477554f786eSSteven Rostedt if (!cpumask_test_cpu(cpu, buffer->cpumask)) 4478554f786eSSteven Rostedt goto out; 4479554f786eSSteven Rostedt 4480474d32b6SSteven Rostedt /* 4481474d32b6SSteven Rostedt * If len is not big enough to hold the page header, then 4482474d32b6SSteven Rostedt * we can not copy anything. 4483474d32b6SSteven Rostedt */ 4484474d32b6SSteven Rostedt if (len <= BUF_PAGE_HDR_SIZE) 4485554f786eSSteven Rostedt goto out; 4486474d32b6SSteven Rostedt 4487474d32b6SSteven Rostedt len -= BUF_PAGE_HDR_SIZE; 4488474d32b6SSteven Rostedt 44898789a9e7SSteven Rostedt if (!data_page) 4490554f786eSSteven Rostedt goto out; 44918789a9e7SSteven Rostedt 4492044fa782SSteven Rostedt bpage = *data_page; 4493044fa782SSteven Rostedt if (!bpage) 4494554f786eSSteven Rostedt goto out; 44958789a9e7SSteven Rostedt 44965389f6faSThomas Gleixner raw_spin_lock_irqsave(&cpu_buffer->reader_lock, flags); 44978789a9e7SSteven Rostedt 4498ef7a4a16SSteven Rostedt reader = rb_get_reader_page(cpu_buffer); 4499ef7a4a16SSteven Rostedt if (!reader) 4500554f786eSSteven Rostedt goto out_unlock; 45018789a9e7SSteven Rostedt 4502ef7a4a16SSteven Rostedt event = rb_reader_event(cpu_buffer); 4503667d2412SLai Jiangshan 4504ef7a4a16SSteven Rostedt read = reader->read; 4505ef7a4a16SSteven Rostedt commit = rb_page_commit(reader); 4506ef7a4a16SSteven Rostedt 450766a8cb95SSteven Rostedt /* Check if any events were dropped */ 4508ff0ff84aSSteven Rostedt missed_events = cpu_buffer->lost_events; 450966a8cb95SSteven Rostedt 45108789a9e7SSteven Rostedt /* 4511474d32b6SSteven Rostedt * If this page has been partially read or 4512474d32b6SSteven Rostedt * if len is not big enough to read the rest of the page or 4513474d32b6SSteven Rostedt * a writer is still on the page, then 4514474d32b6SSteven Rostedt * we must copy the data from the page to the buffer. 4515474d32b6SSteven Rostedt * Otherwise, we can simply swap the page with the one passed in. 45168789a9e7SSteven Rostedt */ 4517474d32b6SSteven Rostedt if (read || (len < (commit - read)) || 4518ef7a4a16SSteven Rostedt cpu_buffer->reader_page == cpu_buffer->commit_page) { 4519667d2412SLai Jiangshan struct buffer_data_page *rpage = cpu_buffer->reader_page->page; 4520474d32b6SSteven Rostedt unsigned int rpos = read; 4521474d32b6SSteven Rostedt unsigned int pos = 0; 4522ef7a4a16SSteven Rostedt unsigned int size; 45238789a9e7SSteven Rostedt 45248789a9e7SSteven Rostedt if (full) 4525554f786eSSteven Rostedt goto out_unlock; 45268789a9e7SSteven Rostedt 4527ef7a4a16SSteven Rostedt if (len > (commit - read)) 4528ef7a4a16SSteven Rostedt len = (commit - read); 4529ef7a4a16SSteven Rostedt 453069d1b839SSteven Rostedt /* Always keep the time extend and data together */ 453169d1b839SSteven Rostedt size = rb_event_ts_length(event); 4532ef7a4a16SSteven Rostedt 4533ef7a4a16SSteven Rostedt if (len < size) 4534554f786eSSteven Rostedt goto out_unlock; 4535ef7a4a16SSteven Rostedt 45364f3640f8SSteven Rostedt /* save the current timestamp, since the user will need it */ 45374f3640f8SSteven Rostedt save_timestamp = cpu_buffer->read_stamp; 45384f3640f8SSteven Rostedt 4539ef7a4a16SSteven Rostedt /* Need to copy one event at a time */ 4540ef7a4a16SSteven Rostedt do { 4541e1e35927SDavid Sharp /* We need the size of one event, because 4542e1e35927SDavid Sharp * rb_advance_reader only advances by one event, 4543e1e35927SDavid Sharp * whereas rb_event_ts_length may include the size of 4544e1e35927SDavid Sharp * one or two events. 4545e1e35927SDavid Sharp * We have already ensured there's enough space if this 4546e1e35927SDavid Sharp * is a time extend. */ 4547e1e35927SDavid Sharp size = rb_event_length(event); 4548474d32b6SSteven Rostedt memcpy(bpage->data + pos, rpage->data + rpos, size); 4549ef7a4a16SSteven Rostedt 4550ef7a4a16SSteven Rostedt len -= size; 4551ef7a4a16SSteven Rostedt 4552ef7a4a16SSteven Rostedt rb_advance_reader(cpu_buffer); 4553474d32b6SSteven Rostedt rpos = reader->read; 4554474d32b6SSteven Rostedt pos += size; 4555ef7a4a16SSteven Rostedt 455618fab912SHuang Ying if (rpos >= commit) 455718fab912SHuang Ying break; 455818fab912SHuang Ying 4559ef7a4a16SSteven Rostedt event = rb_reader_event(cpu_buffer); 456069d1b839SSteven Rostedt /* Always keep the time extend and data together */ 456169d1b839SSteven Rostedt size = rb_event_ts_length(event); 4562e1e35927SDavid Sharp } while (len >= size); 4563667d2412SLai Jiangshan 4564667d2412SLai Jiangshan /* update bpage */ 4565ef7a4a16SSteven Rostedt local_set(&bpage->commit, pos); 45664f3640f8SSteven Rostedt bpage->time_stamp = save_timestamp; 4567ef7a4a16SSteven Rostedt 4568474d32b6SSteven Rostedt /* we copied everything to the beginning */ 4569474d32b6SSteven Rostedt read = 0; 45708789a9e7SSteven Rostedt } else { 4571afbab76aSSteven Rostedt /* update the entry counter */ 457277ae365eSSteven Rostedt cpu_buffer->read += rb_page_entries(reader); 4573c64e148aSVaibhav Nagarnaik cpu_buffer->read_bytes += BUF_PAGE_SIZE; 4574afbab76aSSteven Rostedt 45758789a9e7SSteven Rostedt /* swap the pages */ 4576044fa782SSteven Rostedt rb_init_page(bpage); 4577ef7a4a16SSteven Rostedt bpage = reader->page; 4578ef7a4a16SSteven Rostedt reader->page = *data_page; 4579ef7a4a16SSteven Rostedt local_set(&reader->write, 0); 4580778c55d4SSteven Rostedt local_set(&reader->entries, 0); 4581ef7a4a16SSteven Rostedt reader->read = 0; 4582044fa782SSteven Rostedt *data_page = bpage; 4583ff0ff84aSSteven Rostedt 4584ff0ff84aSSteven Rostedt /* 4585ff0ff84aSSteven Rostedt * Use the real_end for the data size, 4586ff0ff84aSSteven Rostedt * This gives us a chance to store the lost events 4587ff0ff84aSSteven Rostedt * on the page. 4588ff0ff84aSSteven Rostedt */ 4589ff0ff84aSSteven Rostedt if (reader->real_end) 4590ff0ff84aSSteven Rostedt local_set(&bpage->commit, reader->real_end); 4591ef7a4a16SSteven Rostedt } 4592ef7a4a16SSteven Rostedt ret = read; 4593ef7a4a16SSteven Rostedt 459466a8cb95SSteven Rostedt cpu_buffer->lost_events = 0; 45952711ca23SSteven Rostedt 45962711ca23SSteven Rostedt commit = local_read(&bpage->commit); 459766a8cb95SSteven Rostedt /* 459866a8cb95SSteven Rostedt * Set a flag in the commit field if we lost events 459966a8cb95SSteven Rostedt */ 4600ff0ff84aSSteven Rostedt if (missed_events) { 4601ff0ff84aSSteven Rostedt /* If there is room at the end of the page to save the 4602ff0ff84aSSteven Rostedt * missed events, then record it there. 4603ff0ff84aSSteven Rostedt */ 4604ff0ff84aSSteven Rostedt if (BUF_PAGE_SIZE - commit >= sizeof(missed_events)) { 4605ff0ff84aSSteven Rostedt memcpy(&bpage->data[commit], &missed_events, 4606ff0ff84aSSteven Rostedt sizeof(missed_events)); 4607ff0ff84aSSteven Rostedt local_add(RB_MISSED_STORED, &bpage->commit); 46082711ca23SSteven Rostedt commit += sizeof(missed_events); 4609ff0ff84aSSteven Rostedt } 461066a8cb95SSteven Rostedt local_add(RB_MISSED_EVENTS, &bpage->commit); 4611ff0ff84aSSteven Rostedt } 461266a8cb95SSteven Rostedt 46132711ca23SSteven Rostedt /* 46142711ca23SSteven Rostedt * This page may be off to user land. Zero it out here. 46152711ca23SSteven Rostedt */ 46162711ca23SSteven Rostedt if (commit < BUF_PAGE_SIZE) 46172711ca23SSteven Rostedt memset(&bpage->data[commit], 0, BUF_PAGE_SIZE - commit); 46182711ca23SSteven Rostedt 4619554f786eSSteven Rostedt out_unlock: 46205389f6faSThomas Gleixner raw_spin_unlock_irqrestore(&cpu_buffer->reader_lock, flags); 46218789a9e7SSteven Rostedt 4622554f786eSSteven Rostedt out: 46238789a9e7SSteven Rostedt return ret; 46248789a9e7SSteven Rostedt } 4625d6ce96daSSteven Rostedt EXPORT_SYMBOL_GPL(ring_buffer_read_page); 46268789a9e7SSteven Rostedt 4627b32614c0SSebastian Andrzej Siewior /* 4628b32614c0SSebastian Andrzej Siewior * We only allocate new buffers, never free them if the CPU goes down. 4629b32614c0SSebastian Andrzej Siewior * If we were to free the buffer, then the user would lose any trace that was in 4630b32614c0SSebastian Andrzej Siewior * the buffer. 4631b32614c0SSebastian Andrzej Siewior */ 4632b32614c0SSebastian Andrzej Siewior int trace_rb_cpu_prepare(unsigned int cpu, struct hlist_node *node) 4633554f786eSSteven Rostedt { 4634b32614c0SSebastian Andrzej Siewior struct ring_buffer *buffer; 46359b94a8fbSSteven Rostedt (Red Hat) long nr_pages_same; 46369b94a8fbSSteven Rostedt (Red Hat) int cpu_i; 46379b94a8fbSSteven Rostedt (Red Hat) unsigned long nr_pages; 4638554f786eSSteven Rostedt 4639b32614c0SSebastian Andrzej Siewior buffer = container_of(node, struct ring_buffer, node); 46403f237a79SRusty Russell if (cpumask_test_cpu(cpu, buffer->cpumask)) 4641b32614c0SSebastian Andrzej Siewior return 0; 4642554f786eSSteven Rostedt 4643438ced17SVaibhav Nagarnaik nr_pages = 0; 4644438ced17SVaibhav Nagarnaik nr_pages_same = 1; 4645438ced17SVaibhav Nagarnaik /* check if all cpu sizes are same */ 4646438ced17SVaibhav Nagarnaik for_each_buffer_cpu(buffer, cpu_i) { 4647438ced17SVaibhav Nagarnaik /* fill in the size from first enabled cpu */ 4648438ced17SVaibhav Nagarnaik if (nr_pages == 0) 4649438ced17SVaibhav Nagarnaik nr_pages = buffer->buffers[cpu_i]->nr_pages; 4650438ced17SVaibhav Nagarnaik if (nr_pages != buffer->buffers[cpu_i]->nr_pages) { 4651438ced17SVaibhav Nagarnaik nr_pages_same = 0; 4652438ced17SVaibhav Nagarnaik break; 4653438ced17SVaibhav Nagarnaik } 4654438ced17SVaibhav Nagarnaik } 4655438ced17SVaibhav Nagarnaik /* allocate minimum pages, user can later expand it */ 4656438ced17SVaibhav Nagarnaik if (!nr_pages_same) 4657438ced17SVaibhav Nagarnaik nr_pages = 2; 4658554f786eSSteven Rostedt buffer->buffers[cpu] = 4659438ced17SVaibhav Nagarnaik rb_allocate_cpu_buffer(buffer, nr_pages, cpu); 4660554f786eSSteven Rostedt if (!buffer->buffers[cpu]) { 4661b32614c0SSebastian Andrzej Siewior WARN(1, "failed to allocate ring buffer on CPU %u\n", 4662554f786eSSteven Rostedt cpu); 4663b32614c0SSebastian Andrzej Siewior return -ENOMEM; 4664554f786eSSteven Rostedt } 4665554f786eSSteven Rostedt smp_wmb(); 46663f237a79SRusty Russell cpumask_set_cpu(cpu, buffer->cpumask); 4667b32614c0SSebastian Andrzej Siewior return 0; 4668554f786eSSteven Rostedt } 46696c43e554SSteven Rostedt (Red Hat) 46706c43e554SSteven Rostedt (Red Hat) #ifdef CONFIG_RING_BUFFER_STARTUP_TEST 46716c43e554SSteven Rostedt (Red Hat) /* 46726c43e554SSteven Rostedt (Red Hat) * This is a basic integrity check of the ring buffer. 46736c43e554SSteven Rostedt (Red Hat) * Late in the boot cycle this test will run when configured in. 46746c43e554SSteven Rostedt (Red Hat) * It will kick off a thread per CPU that will go into a loop 46756c43e554SSteven Rostedt (Red Hat) * writing to the per cpu ring buffer various sizes of data. 46766c43e554SSteven Rostedt (Red Hat) * Some of the data will be large items, some small. 46776c43e554SSteven Rostedt (Red Hat) * 46786c43e554SSteven Rostedt (Red Hat) * Another thread is created that goes into a spin, sending out 46796c43e554SSteven Rostedt (Red Hat) * IPIs to the other CPUs to also write into the ring buffer. 46806c43e554SSteven Rostedt (Red Hat) * this is to test the nesting ability of the buffer. 46816c43e554SSteven Rostedt (Red Hat) * 46826c43e554SSteven Rostedt (Red Hat) * Basic stats are recorded and reported. If something in the 46836c43e554SSteven Rostedt (Red Hat) * ring buffer should happen that's not expected, a big warning 46846c43e554SSteven Rostedt (Red Hat) * is displayed and all ring buffers are disabled. 46856c43e554SSteven Rostedt (Red Hat) */ 46866c43e554SSteven Rostedt (Red Hat) static struct task_struct *rb_threads[NR_CPUS] __initdata; 46876c43e554SSteven Rostedt (Red Hat) 46886c43e554SSteven Rostedt (Red Hat) struct rb_test_data { 46896c43e554SSteven Rostedt (Red Hat) struct ring_buffer *buffer; 46906c43e554SSteven Rostedt (Red Hat) unsigned long events; 46916c43e554SSteven Rostedt (Red Hat) unsigned long bytes_written; 46926c43e554SSteven Rostedt (Red Hat) unsigned long bytes_alloc; 46936c43e554SSteven Rostedt (Red Hat) unsigned long bytes_dropped; 46946c43e554SSteven Rostedt (Red Hat) unsigned long events_nested; 46956c43e554SSteven Rostedt (Red Hat) unsigned long bytes_written_nested; 46966c43e554SSteven Rostedt (Red Hat) unsigned long bytes_alloc_nested; 46976c43e554SSteven Rostedt (Red Hat) unsigned long bytes_dropped_nested; 46986c43e554SSteven Rostedt (Red Hat) int min_size_nested; 46996c43e554SSteven Rostedt (Red Hat) int max_size_nested; 47006c43e554SSteven Rostedt (Red Hat) int max_size; 47016c43e554SSteven Rostedt (Red Hat) int min_size; 47026c43e554SSteven Rostedt (Red Hat) int cpu; 47036c43e554SSteven Rostedt (Red Hat) int cnt; 47046c43e554SSteven Rostedt (Red Hat) }; 47056c43e554SSteven Rostedt (Red Hat) 47066c43e554SSteven Rostedt (Red Hat) static struct rb_test_data rb_data[NR_CPUS] __initdata; 47076c43e554SSteven Rostedt (Red Hat) 47086c43e554SSteven Rostedt (Red Hat) /* 1 meg per cpu */ 47096c43e554SSteven Rostedt (Red Hat) #define RB_TEST_BUFFER_SIZE 1048576 47106c43e554SSteven Rostedt (Red Hat) 47116c43e554SSteven Rostedt (Red Hat) static char rb_string[] __initdata = 47126c43e554SSteven Rostedt (Red Hat) "abcdefghijklmnopqrstuvwxyz1234567890!@#$%^&*()?+\\" 47136c43e554SSteven Rostedt (Red Hat) "?+|:';\",.<>/?abcdefghijklmnopqrstuvwxyz1234567890" 47146c43e554SSteven Rostedt (Red Hat) "!@#$%^&*()?+\\?+|:';\",.<>/?abcdefghijklmnopqrstuv"; 47156c43e554SSteven Rostedt (Red Hat) 47166c43e554SSteven Rostedt (Red Hat) static bool rb_test_started __initdata; 47176c43e554SSteven Rostedt (Red Hat) 47186c43e554SSteven Rostedt (Red Hat) struct rb_item { 47196c43e554SSteven Rostedt (Red Hat) int size; 47206c43e554SSteven Rostedt (Red Hat) char str[]; 47216c43e554SSteven Rostedt (Red Hat) }; 47226c43e554SSteven Rostedt (Red Hat) 47236c43e554SSteven Rostedt (Red Hat) static __init int rb_write_something(struct rb_test_data *data, bool nested) 47246c43e554SSteven Rostedt (Red Hat) { 47256c43e554SSteven Rostedt (Red Hat) struct ring_buffer_event *event; 47266c43e554SSteven Rostedt (Red Hat) struct rb_item *item; 47276c43e554SSteven Rostedt (Red Hat) bool started; 47286c43e554SSteven Rostedt (Red Hat) int event_len; 47296c43e554SSteven Rostedt (Red Hat) int size; 47306c43e554SSteven Rostedt (Red Hat) int len; 47316c43e554SSteven Rostedt (Red Hat) int cnt; 47326c43e554SSteven Rostedt (Red Hat) 47336c43e554SSteven Rostedt (Red Hat) /* Have nested writes different that what is written */ 47346c43e554SSteven Rostedt (Red Hat) cnt = data->cnt + (nested ? 27 : 0); 47356c43e554SSteven Rostedt (Red Hat) 47366c43e554SSteven Rostedt (Red Hat) /* Multiply cnt by ~e, to make some unique increment */ 47376c43e554SSteven Rostedt (Red Hat) size = (data->cnt * 68 / 25) % (sizeof(rb_string) - 1); 47386c43e554SSteven Rostedt (Red Hat) 47396c43e554SSteven Rostedt (Red Hat) len = size + sizeof(struct rb_item); 47406c43e554SSteven Rostedt (Red Hat) 47416c43e554SSteven Rostedt (Red Hat) started = rb_test_started; 47426c43e554SSteven Rostedt (Red Hat) /* read rb_test_started before checking buffer enabled */ 47436c43e554SSteven Rostedt (Red Hat) smp_rmb(); 47446c43e554SSteven Rostedt (Red Hat) 47456c43e554SSteven Rostedt (Red Hat) event = ring_buffer_lock_reserve(data->buffer, len); 47466c43e554SSteven Rostedt (Red Hat) if (!event) { 47476c43e554SSteven Rostedt (Red Hat) /* Ignore dropped events before test starts. */ 47486c43e554SSteven Rostedt (Red Hat) if (started) { 47496c43e554SSteven Rostedt (Red Hat) if (nested) 47506c43e554SSteven Rostedt (Red Hat) data->bytes_dropped += len; 47516c43e554SSteven Rostedt (Red Hat) else 47526c43e554SSteven Rostedt (Red Hat) data->bytes_dropped_nested += len; 47536c43e554SSteven Rostedt (Red Hat) } 47546c43e554SSteven Rostedt (Red Hat) return len; 47556c43e554SSteven Rostedt (Red Hat) } 47566c43e554SSteven Rostedt (Red Hat) 47576c43e554SSteven Rostedt (Red Hat) event_len = ring_buffer_event_length(event); 47586c43e554SSteven Rostedt (Red Hat) 47596c43e554SSteven Rostedt (Red Hat) if (RB_WARN_ON(data->buffer, event_len < len)) 47606c43e554SSteven Rostedt (Red Hat) goto out; 47616c43e554SSteven Rostedt (Red Hat) 47626c43e554SSteven Rostedt (Red Hat) item = ring_buffer_event_data(event); 47636c43e554SSteven Rostedt (Red Hat) item->size = size; 47646c43e554SSteven Rostedt (Red Hat) memcpy(item->str, rb_string, size); 47656c43e554SSteven Rostedt (Red Hat) 47666c43e554SSteven Rostedt (Red Hat) if (nested) { 47676c43e554SSteven Rostedt (Red Hat) data->bytes_alloc_nested += event_len; 47686c43e554SSteven Rostedt (Red Hat) data->bytes_written_nested += len; 47696c43e554SSteven Rostedt (Red Hat) data->events_nested++; 47706c43e554SSteven Rostedt (Red Hat) if (!data->min_size_nested || len < data->min_size_nested) 47716c43e554SSteven Rostedt (Red Hat) data->min_size_nested = len; 47726c43e554SSteven Rostedt (Red Hat) if (len > data->max_size_nested) 47736c43e554SSteven Rostedt (Red Hat) data->max_size_nested = len; 47746c43e554SSteven Rostedt (Red Hat) } else { 47756c43e554SSteven Rostedt (Red Hat) data->bytes_alloc += event_len; 47766c43e554SSteven Rostedt (Red Hat) data->bytes_written += len; 47776c43e554SSteven Rostedt (Red Hat) data->events++; 47786c43e554SSteven Rostedt (Red Hat) if (!data->min_size || len < data->min_size) 47796c43e554SSteven Rostedt (Red Hat) data->max_size = len; 47806c43e554SSteven Rostedt (Red Hat) if (len > data->max_size) 47816c43e554SSteven Rostedt (Red Hat) data->max_size = len; 47826c43e554SSteven Rostedt (Red Hat) } 47836c43e554SSteven Rostedt (Red Hat) 47846c43e554SSteven Rostedt (Red Hat) out: 47856c43e554SSteven Rostedt (Red Hat) ring_buffer_unlock_commit(data->buffer, event); 47866c43e554SSteven Rostedt (Red Hat) 47876c43e554SSteven Rostedt (Red Hat) return 0; 47886c43e554SSteven Rostedt (Red Hat) } 47896c43e554SSteven Rostedt (Red Hat) 47906c43e554SSteven Rostedt (Red Hat) static __init int rb_test(void *arg) 47916c43e554SSteven Rostedt (Red Hat) { 47926c43e554SSteven Rostedt (Red Hat) struct rb_test_data *data = arg; 47936c43e554SSteven Rostedt (Red Hat) 47946c43e554SSteven Rostedt (Red Hat) while (!kthread_should_stop()) { 47956c43e554SSteven Rostedt (Red Hat) rb_write_something(data, false); 47966c43e554SSteven Rostedt (Red Hat) data->cnt++; 47976c43e554SSteven Rostedt (Red Hat) 47986c43e554SSteven Rostedt (Red Hat) set_current_state(TASK_INTERRUPTIBLE); 47996c43e554SSteven Rostedt (Red Hat) /* Now sleep between a min of 100-300us and a max of 1ms */ 48006c43e554SSteven Rostedt (Red Hat) usleep_range(((data->cnt % 3) + 1) * 100, 1000); 48016c43e554SSteven Rostedt (Red Hat) } 48026c43e554SSteven Rostedt (Red Hat) 48036c43e554SSteven Rostedt (Red Hat) return 0; 48046c43e554SSteven Rostedt (Red Hat) } 48056c43e554SSteven Rostedt (Red Hat) 48066c43e554SSteven Rostedt (Red Hat) static __init void rb_ipi(void *ignore) 48076c43e554SSteven Rostedt (Red Hat) { 48086c43e554SSteven Rostedt (Red Hat) struct rb_test_data *data; 48096c43e554SSteven Rostedt (Red Hat) int cpu = smp_processor_id(); 48106c43e554SSteven Rostedt (Red Hat) 48116c43e554SSteven Rostedt (Red Hat) data = &rb_data[cpu]; 48126c43e554SSteven Rostedt (Red Hat) rb_write_something(data, true); 48136c43e554SSteven Rostedt (Red Hat) } 48146c43e554SSteven Rostedt (Red Hat) 48156c43e554SSteven Rostedt (Red Hat) static __init int rb_hammer_test(void *arg) 48166c43e554SSteven Rostedt (Red Hat) { 48176c43e554SSteven Rostedt (Red Hat) while (!kthread_should_stop()) { 48186c43e554SSteven Rostedt (Red Hat) 48196c43e554SSteven Rostedt (Red Hat) /* Send an IPI to all cpus to write data! */ 48206c43e554SSteven Rostedt (Red Hat) smp_call_function(rb_ipi, NULL, 1); 48216c43e554SSteven Rostedt (Red Hat) /* No sleep, but for non preempt, let others run */ 48226c43e554SSteven Rostedt (Red Hat) schedule(); 48236c43e554SSteven Rostedt (Red Hat) } 48246c43e554SSteven Rostedt (Red Hat) 48256c43e554SSteven Rostedt (Red Hat) return 0; 48266c43e554SSteven Rostedt (Red Hat) } 48276c43e554SSteven Rostedt (Red Hat) 48286c43e554SSteven Rostedt (Red Hat) static __init int test_ringbuffer(void) 48296c43e554SSteven Rostedt (Red Hat) { 48306c43e554SSteven Rostedt (Red Hat) struct task_struct *rb_hammer; 48316c43e554SSteven Rostedt (Red Hat) struct ring_buffer *buffer; 48326c43e554SSteven Rostedt (Red Hat) int cpu; 48336c43e554SSteven Rostedt (Red Hat) int ret = 0; 48346c43e554SSteven Rostedt (Red Hat) 48356c43e554SSteven Rostedt (Red Hat) pr_info("Running ring buffer tests...\n"); 48366c43e554SSteven Rostedt (Red Hat) 48376c43e554SSteven Rostedt (Red Hat) buffer = ring_buffer_alloc(RB_TEST_BUFFER_SIZE, RB_FL_OVERWRITE); 48386c43e554SSteven Rostedt (Red Hat) if (WARN_ON(!buffer)) 48396c43e554SSteven Rostedt (Red Hat) return 0; 48406c43e554SSteven Rostedt (Red Hat) 48416c43e554SSteven Rostedt (Red Hat) /* Disable buffer so that threads can't write to it yet */ 48426c43e554SSteven Rostedt (Red Hat) ring_buffer_record_off(buffer); 48436c43e554SSteven Rostedt (Red Hat) 48446c43e554SSteven Rostedt (Red Hat) for_each_online_cpu(cpu) { 48456c43e554SSteven Rostedt (Red Hat) rb_data[cpu].buffer = buffer; 48466c43e554SSteven Rostedt (Red Hat) rb_data[cpu].cpu = cpu; 48476c43e554SSteven Rostedt (Red Hat) rb_data[cpu].cnt = cpu; 48486c43e554SSteven Rostedt (Red Hat) rb_threads[cpu] = kthread_create(rb_test, &rb_data[cpu], 48496c43e554SSteven Rostedt (Red Hat) "rbtester/%d", cpu); 485062277de7SWei Yongjun if (WARN_ON(IS_ERR(rb_threads[cpu]))) { 48516c43e554SSteven Rostedt (Red Hat) pr_cont("FAILED\n"); 485262277de7SWei Yongjun ret = PTR_ERR(rb_threads[cpu]); 48536c43e554SSteven Rostedt (Red Hat) goto out_free; 48546c43e554SSteven Rostedt (Red Hat) } 48556c43e554SSteven Rostedt (Red Hat) 48566c43e554SSteven Rostedt (Red Hat) kthread_bind(rb_threads[cpu], cpu); 48576c43e554SSteven Rostedt (Red Hat) wake_up_process(rb_threads[cpu]); 48586c43e554SSteven Rostedt (Red Hat) } 48596c43e554SSteven Rostedt (Red Hat) 48606c43e554SSteven Rostedt (Red Hat) /* Now create the rb hammer! */ 48616c43e554SSteven Rostedt (Red Hat) rb_hammer = kthread_run(rb_hammer_test, NULL, "rbhammer"); 486262277de7SWei Yongjun if (WARN_ON(IS_ERR(rb_hammer))) { 48636c43e554SSteven Rostedt (Red Hat) pr_cont("FAILED\n"); 486462277de7SWei Yongjun ret = PTR_ERR(rb_hammer); 48656c43e554SSteven Rostedt (Red Hat) goto out_free; 48666c43e554SSteven Rostedt (Red Hat) } 48676c43e554SSteven Rostedt (Red Hat) 48686c43e554SSteven Rostedt (Red Hat) ring_buffer_record_on(buffer); 48696c43e554SSteven Rostedt (Red Hat) /* 48706c43e554SSteven Rostedt (Red Hat) * Show buffer is enabled before setting rb_test_started. 48716c43e554SSteven Rostedt (Red Hat) * Yes there's a small race window where events could be 48726c43e554SSteven Rostedt (Red Hat) * dropped and the thread wont catch it. But when a ring 48736c43e554SSteven Rostedt (Red Hat) * buffer gets enabled, there will always be some kind of 48746c43e554SSteven Rostedt (Red Hat) * delay before other CPUs see it. Thus, we don't care about 48756c43e554SSteven Rostedt (Red Hat) * those dropped events. We care about events dropped after 48766c43e554SSteven Rostedt (Red Hat) * the threads see that the buffer is active. 48776c43e554SSteven Rostedt (Red Hat) */ 48786c43e554SSteven Rostedt (Red Hat) smp_wmb(); 48796c43e554SSteven Rostedt (Red Hat) rb_test_started = true; 48806c43e554SSteven Rostedt (Red Hat) 48816c43e554SSteven Rostedt (Red Hat) set_current_state(TASK_INTERRUPTIBLE); 48826c43e554SSteven Rostedt (Red Hat) /* Just run for 10 seconds */; 48836c43e554SSteven Rostedt (Red Hat) schedule_timeout(10 * HZ); 48846c43e554SSteven Rostedt (Red Hat) 48856c43e554SSteven Rostedt (Red Hat) kthread_stop(rb_hammer); 48866c43e554SSteven Rostedt (Red Hat) 48876c43e554SSteven Rostedt (Red Hat) out_free: 48886c43e554SSteven Rostedt (Red Hat) for_each_online_cpu(cpu) { 48896c43e554SSteven Rostedt (Red Hat) if (!rb_threads[cpu]) 48906c43e554SSteven Rostedt (Red Hat) break; 48916c43e554SSteven Rostedt (Red Hat) kthread_stop(rb_threads[cpu]); 48926c43e554SSteven Rostedt (Red Hat) } 48936c43e554SSteven Rostedt (Red Hat) if (ret) { 48946c43e554SSteven Rostedt (Red Hat) ring_buffer_free(buffer); 48956c43e554SSteven Rostedt (Red Hat) return ret; 48966c43e554SSteven Rostedt (Red Hat) } 48976c43e554SSteven Rostedt (Red Hat) 48986c43e554SSteven Rostedt (Red Hat) /* Report! */ 48996c43e554SSteven Rostedt (Red Hat) pr_info("finished\n"); 49006c43e554SSteven Rostedt (Red Hat) for_each_online_cpu(cpu) { 49016c43e554SSteven Rostedt (Red Hat) struct ring_buffer_event *event; 49026c43e554SSteven Rostedt (Red Hat) struct rb_test_data *data = &rb_data[cpu]; 49036c43e554SSteven Rostedt (Red Hat) struct rb_item *item; 49046c43e554SSteven Rostedt (Red Hat) unsigned long total_events; 49056c43e554SSteven Rostedt (Red Hat) unsigned long total_dropped; 49066c43e554SSteven Rostedt (Red Hat) unsigned long total_written; 49076c43e554SSteven Rostedt (Red Hat) unsigned long total_alloc; 49086c43e554SSteven Rostedt (Red Hat) unsigned long total_read = 0; 49096c43e554SSteven Rostedt (Red Hat) unsigned long total_size = 0; 49106c43e554SSteven Rostedt (Red Hat) unsigned long total_len = 0; 49116c43e554SSteven Rostedt (Red Hat) unsigned long total_lost = 0; 49126c43e554SSteven Rostedt (Red Hat) unsigned long lost; 49136c43e554SSteven Rostedt (Red Hat) int big_event_size; 49146c43e554SSteven Rostedt (Red Hat) int small_event_size; 49156c43e554SSteven Rostedt (Red Hat) 49166c43e554SSteven Rostedt (Red Hat) ret = -1; 49176c43e554SSteven Rostedt (Red Hat) 49186c43e554SSteven Rostedt (Red Hat) total_events = data->events + data->events_nested; 49196c43e554SSteven Rostedt (Red Hat) total_written = data->bytes_written + data->bytes_written_nested; 49206c43e554SSteven Rostedt (Red Hat) total_alloc = data->bytes_alloc + data->bytes_alloc_nested; 49216c43e554SSteven Rostedt (Red Hat) total_dropped = data->bytes_dropped + data->bytes_dropped_nested; 49226c43e554SSteven Rostedt (Red Hat) 49236c43e554SSteven Rostedt (Red Hat) big_event_size = data->max_size + data->max_size_nested; 49246c43e554SSteven Rostedt (Red Hat) small_event_size = data->min_size + data->min_size_nested; 49256c43e554SSteven Rostedt (Red Hat) 49266c43e554SSteven Rostedt (Red Hat) pr_info("CPU %d:\n", cpu); 49276c43e554SSteven Rostedt (Red Hat) pr_info(" events: %ld\n", total_events); 49286c43e554SSteven Rostedt (Red Hat) pr_info(" dropped bytes: %ld\n", total_dropped); 49296c43e554SSteven Rostedt (Red Hat) pr_info(" alloced bytes: %ld\n", total_alloc); 49306c43e554SSteven Rostedt (Red Hat) pr_info(" written bytes: %ld\n", total_written); 49316c43e554SSteven Rostedt (Red Hat) pr_info(" biggest event: %d\n", big_event_size); 49326c43e554SSteven Rostedt (Red Hat) pr_info(" smallest event: %d\n", small_event_size); 49336c43e554SSteven Rostedt (Red Hat) 49346c43e554SSteven Rostedt (Red Hat) if (RB_WARN_ON(buffer, total_dropped)) 49356c43e554SSteven Rostedt (Red Hat) break; 49366c43e554SSteven Rostedt (Red Hat) 49376c43e554SSteven Rostedt (Red Hat) ret = 0; 49386c43e554SSteven Rostedt (Red Hat) 49396c43e554SSteven Rostedt (Red Hat) while ((event = ring_buffer_consume(buffer, cpu, NULL, &lost))) { 49406c43e554SSteven Rostedt (Red Hat) total_lost += lost; 49416c43e554SSteven Rostedt (Red Hat) item = ring_buffer_event_data(event); 49426c43e554SSteven Rostedt (Red Hat) total_len += ring_buffer_event_length(event); 49436c43e554SSteven Rostedt (Red Hat) total_size += item->size + sizeof(struct rb_item); 49446c43e554SSteven Rostedt (Red Hat) if (memcmp(&item->str[0], rb_string, item->size) != 0) { 49456c43e554SSteven Rostedt (Red Hat) pr_info("FAILED!\n"); 49466c43e554SSteven Rostedt (Red Hat) pr_info("buffer had: %.*s\n", item->size, item->str); 49476c43e554SSteven Rostedt (Red Hat) pr_info("expected: %.*s\n", item->size, rb_string); 49486c43e554SSteven Rostedt (Red Hat) RB_WARN_ON(buffer, 1); 49496c43e554SSteven Rostedt (Red Hat) ret = -1; 49506c43e554SSteven Rostedt (Red Hat) break; 49516c43e554SSteven Rostedt (Red Hat) } 49526c43e554SSteven Rostedt (Red Hat) total_read++; 49536c43e554SSteven Rostedt (Red Hat) } 49546c43e554SSteven Rostedt (Red Hat) if (ret) 49556c43e554SSteven Rostedt (Red Hat) break; 49566c43e554SSteven Rostedt (Red Hat) 49576c43e554SSteven Rostedt (Red Hat) ret = -1; 49586c43e554SSteven Rostedt (Red Hat) 49596c43e554SSteven Rostedt (Red Hat) pr_info(" read events: %ld\n", total_read); 49606c43e554SSteven Rostedt (Red Hat) pr_info(" lost events: %ld\n", total_lost); 49616c43e554SSteven Rostedt (Red Hat) pr_info(" total events: %ld\n", total_lost + total_read); 49626c43e554SSteven Rostedt (Red Hat) pr_info(" recorded len bytes: %ld\n", total_len); 49636c43e554SSteven Rostedt (Red Hat) pr_info(" recorded size bytes: %ld\n", total_size); 49646c43e554SSteven Rostedt (Red Hat) if (total_lost) 49656c43e554SSteven Rostedt (Red Hat) pr_info(" With dropped events, record len and size may not match\n" 49666c43e554SSteven Rostedt (Red Hat) " alloced and written from above\n"); 49676c43e554SSteven Rostedt (Red Hat) if (!total_lost) { 49686c43e554SSteven Rostedt (Red Hat) if (RB_WARN_ON(buffer, total_len != total_alloc || 49696c43e554SSteven Rostedt (Red Hat) total_size != total_written)) 49706c43e554SSteven Rostedt (Red Hat) break; 49716c43e554SSteven Rostedt (Red Hat) } 49726c43e554SSteven Rostedt (Red Hat) if (RB_WARN_ON(buffer, total_lost + total_read != total_events)) 49736c43e554SSteven Rostedt (Red Hat) break; 49746c43e554SSteven Rostedt (Red Hat) 49756c43e554SSteven Rostedt (Red Hat) ret = 0; 49766c43e554SSteven Rostedt (Red Hat) } 49776c43e554SSteven Rostedt (Red Hat) if (!ret) 49786c43e554SSteven Rostedt (Red Hat) pr_info("Ring buffer PASSED!\n"); 49796c43e554SSteven Rostedt (Red Hat) 49806c43e554SSteven Rostedt (Red Hat) ring_buffer_free(buffer); 49816c43e554SSteven Rostedt (Red Hat) return 0; 49826c43e554SSteven Rostedt (Red Hat) } 49836c43e554SSteven Rostedt (Red Hat) 49846c43e554SSteven Rostedt (Red Hat) late_initcall(test_ringbuffer); 49856c43e554SSteven Rostedt (Red Hat) #endif /* CONFIG_RING_BUFFER_STARTUP_TEST */ 4986