void lib_ring_buffer_backend_reset(struct lttng_ust_lib_ring_buffer_backend *bufb, struct lttng_ust_shm_handle *handle) { struct channel_backend *chanb; const struct lttng_ust_lib_ring_buffer_config *config; unsigned long num_subbuf_alloc; unsigned int i; chanb = &shmp(handle, bufb->chan)->backend; if (!chanb) abort(); config = &chanb->config; num_subbuf_alloc = chanb->num_subbuf; if (chanb->extra_reader_sb) num_subbuf_alloc++; for (i = 0; i < chanb->num_subbuf; i++) { struct lttng_ust_lib_ring_buffer_backend_subbuffer *sb; sb = shmp_index(handle, bufb->buf_wsb, i); if (!sb) abort(); sb->id = subbuffer_id(config, 0, 1, i); } if (chanb->extra_reader_sb) bufb->buf_rsb.id = subbuffer_id(config, 0, 1, num_subbuf_alloc - 1); else bufb->buf_rsb.id = subbuffer_id(config, 0, 1, 0); for (i = 0; i < num_subbuf_alloc; i++) { struct lttng_ust_lib_ring_buffer_backend_pages_shmp *sbp; struct lttng_ust_lib_ring_buffer_backend_pages *pages; sbp = shmp_index(handle, bufb->array, i); if (!sbp) abort(); pages = shmp(handle, sbp->shmp); if (!pages) abort(); /* Don't reset mmap_offset */ v_set(config, &pages->records_commit, 0); v_set(config, &pages->records_unread, 0); pages->data_size = 0; /* Don't reset backend page and virt addresses */ } /* Don't reset num_pages_per_subbuf, cpu, allocated */ v_set(config, &bufb->records_read, 0); }
/* returns the offset of the subbuffer belonging to the mmap reader. */ int ustctl_get_mmap_read_offset(struct lttng_ust_shm_handle *handle, struct lttng_ust_lib_ring_buffer *buf, unsigned long *off) { struct channel *chan = handle->shadow_chan; unsigned long sb_bindex; if (!handle || !buf || !off) return -EINVAL; if (chan->backend.config.output != RING_BUFFER_MMAP) return -EINVAL; sb_bindex = subbuffer_id_get_index(&chan->backend.config, buf->backend.buf_rsb.id); *off = shmp(handle, shmp_index(handle, buf->backend.array, sb_bindex)->shmp)->mmap_offset; return 0; }
/* returns the offset of the subbuffer belonging to the mmap reader. */ int ustctl_get_mmap_read_offset(struct ustctl_consumer_stream *stream, unsigned long *off) { struct channel *chan; unsigned long sb_bindex; struct lttng_ust_lib_ring_buffer *buf; struct ustctl_consumer_channel *consumer_chan; if (!stream) return -EINVAL; buf = stream->buf; consumer_chan = stream->chan; chan = consumer_chan->chan->chan; if (chan->backend.config.output != RING_BUFFER_MMAP) return -EINVAL; sb_bindex = subbuffer_id_get_index(&chan->backend.config, buf->backend.buf_rsb.id); *off = shmp(consumer_chan->chan->handle, shmp_index(consumer_chan->chan->handle, buf->backend.array, sb_bindex)->shmp)->mmap_offset; return 0; }
/** * lib_ring_buffer_backend_allocate - allocate a channel buffer * @config: ring buffer instance configuration * @buf: the buffer struct * @size: total size of the buffer * @num_subbuf: number of subbuffers * @extra_reader_sb: need extra subbuffer for reader */ static int lib_ring_buffer_backend_allocate(const struct lttng_ust_lib_ring_buffer_config *config, struct lttng_ust_lib_ring_buffer_backend *bufb, size_t size, size_t num_subbuf, int extra_reader_sb, struct lttng_ust_shm_handle *handle, struct shm_object *shmobj) { struct channel_backend *chanb; unsigned long subbuf_size, mmap_offset = 0; unsigned long num_subbuf_alloc; unsigned long i; long page_size; chanb = &shmp(handle, bufb->chan)->backend; if (!chanb) return -EINVAL; subbuf_size = chanb->subbuf_size; num_subbuf_alloc = num_subbuf; if (extra_reader_sb) num_subbuf_alloc++; page_size = sysconf(_SC_PAGE_SIZE); if (page_size <= 0) { goto page_size_error; } align_shm(shmobj, __alignof__(struct lttng_ust_lib_ring_buffer_backend_pages_shmp)); set_shmp(bufb->array, zalloc_shm(shmobj, sizeof(struct lttng_ust_lib_ring_buffer_backend_pages_shmp) * num_subbuf_alloc)); if (caa_unlikely(!shmp(handle, bufb->array))) goto array_error; /* * This is the largest element (the buffer pages) which needs to * be aligned on page size. */ align_shm(shmobj, page_size); set_shmp(bufb->memory_map, zalloc_shm(shmobj, subbuf_size * num_subbuf_alloc)); if (caa_unlikely(!shmp(handle, bufb->memory_map))) goto memory_map_error; /* Allocate backend pages array elements */ for (i = 0; i < num_subbuf_alloc; i++) { align_shm(shmobj, __alignof__(struct lttng_ust_lib_ring_buffer_backend_pages)); set_shmp(shmp_index(handle, bufb->array, i)->shmp, zalloc_shm(shmobj, sizeof(struct lttng_ust_lib_ring_buffer_backend_pages))); if (!shmp(handle, shmp_index(handle, bufb->array, i)->shmp)) goto free_array; } /* Allocate write-side subbuffer table */ align_shm(shmobj, __alignof__(struct lttng_ust_lib_ring_buffer_backend_subbuffer)); set_shmp(bufb->buf_wsb, zalloc_shm(shmobj, sizeof(struct lttng_ust_lib_ring_buffer_backend_subbuffer) * num_subbuf)); if (caa_unlikely(!shmp(handle, bufb->buf_wsb))) goto free_array; for (i = 0; i < num_subbuf; i++) { struct lttng_ust_lib_ring_buffer_backend_subbuffer *sb; sb = shmp_index(handle, bufb->buf_wsb, i); if (!sb) goto free_array; sb->id = subbuffer_id(config, 0, 1, i); } /* Assign read-side subbuffer table */ if (extra_reader_sb) bufb->buf_rsb.id = subbuffer_id(config, 0, 1, num_subbuf_alloc - 1); else bufb->buf_rsb.id = subbuffer_id(config, 0, 1, 0); /* Allocate subbuffer packet counter table */ align_shm(shmobj, __alignof__(struct lttng_ust_lib_ring_buffer_backend_subbuffer)); set_shmp(bufb->buf_cnt, zalloc_shm(shmobj, sizeof(struct lttng_ust_lib_ring_buffer_backend_counts) * num_subbuf)); if (caa_unlikely(!shmp(handle, bufb->buf_cnt))) goto free_wsb; /* Assign pages to page index */ for (i = 0; i < num_subbuf_alloc; i++) { struct lttng_ust_lib_ring_buffer_backend_pages_shmp *sbp; struct lttng_ust_lib_ring_buffer_backend_pages *pages; struct shm_ref ref; ref.index = bufb->memory_map._ref.index; ref.offset = bufb->memory_map._ref.offset; ref.offset += i * subbuf_size; sbp = shmp_index(handle, bufb->array, i); if (!sbp) goto free_array; pages = shmp(handle, sbp->shmp); if (!pages) goto free_array; set_shmp(pages->p, ref); if (config->output == RING_BUFFER_MMAP) { pages->mmap_offset = mmap_offset; mmap_offset += subbuf_size; } } return 0; free_wsb: /* bufb->buf_wsb will be freed by shm teardown */ free_array: /* bufb->array[i] will be freed by shm teardown */ memory_map_error: /* bufb->array will be freed by shm teardown */ array_error: page_size_error: return -ENOMEM; }