X-Git-Url: http://git.lttng.org./?a=blobdiff_plain;f=libringbuffer%2Fring_buffer_backend.c;h=6ba0d8b1d44fe4fbb4dbe8989e773a355691c4d2;hb=69e21fdfdb03686626978254eb4e91ab0e2b4a38;hp=2e688b40f4810e1a80c57b7296edafaed7e97c14;hpb=34daae3e48423fc35b363e19136e324f9e31b05a;p=lttng-ust.git diff --git a/libringbuffer/ring_buffer_backend.c b/libringbuffer/ring_buffer_backend.c index 2e688b40..6ba0d8b1 100644 --- a/libringbuffer/ring_buffer_backend.c +++ b/libringbuffer/ring_buffer_backend.c @@ -1,34 +1,26 @@ /* - * ring_buffer_backend.c + * SPDX-License-Identifier: LGPL-2.1-only * * Copyright (C) 2005-2012 Mathieu Desnoyers - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; only - * version 2.1 of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#define _GNU_SOURCE +#define _LGPL_SOURCE +#include +#include #include #include #include -#include +#include +#include + +#include "ringbuffer-config.h" #include "vatomic.h" #include "backend.h" #include "frontend.h" #include "smp.h" #include "shm.h" +#include "ust-compat.h" /** * lib_ring_buffer_backend_allocate - allocate a channel buffer @@ -41,7 +33,7 @@ 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, + size_t size __attribute__((unused)), size_t num_subbuf, int extra_reader_sb, struct lttng_ust_shm_handle *handle, struct shm_object *shmobj) @@ -62,7 +54,7 @@ int lib_ring_buffer_backend_allocate(const struct lttng_ust_lib_ring_buffer_conf if (extra_reader_sb) num_subbuf_alloc++; - page_size = sysconf(_SC_PAGE_SIZE); + page_size = LTTNG_UST_PAGE_SIZE; if (page_size <= 0) { goto page_size_error; } @@ -117,6 +109,14 @@ int lib_ring_buffer_backend_allocate(const struct lttng_ust_lib_ring_buffer_conf 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_counts)); + 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; @@ -141,6 +141,8 @@ int lib_ring_buffer_backend_allocate(const struct lttng_ust_lib_ring_buffer_conf } 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: @@ -176,7 +178,7 @@ void lib_ring_buffer_backend_reset(struct lttng_ust_lib_ring_buffer_backend *buf chanb = &shmp(handle, bufb->chan)->backend; if (!chanb) - abort(); + return; config = &chanb->config; num_subbuf_alloc = chanb->num_subbuf; @@ -188,7 +190,7 @@ void lib_ring_buffer_backend_reset(struct lttng_ust_lib_ring_buffer_backend *buf sb = shmp_index(handle, bufb->buf_wsb, i); if (!sb) - abort(); + return; sb->id = subbuffer_id(config, 0, 1, i); } if (chanb->extra_reader_sb) @@ -203,10 +205,10 @@ void lib_ring_buffer_backend_reset(struct lttng_ust_lib_ring_buffer_backend *buf sbp = shmp_index(handle, bufb->array, i); if (!sbp) - abort(); + return; pages = shmp(handle, sbp->shmp); if (!pages) - abort(); + return; /* Don't reset mmap_offset */ v_set(config, &pages->records_commit, 0); v_set(config, &pages->records_unread, 0); @@ -223,7 +225,8 @@ void lib_ring_buffer_backend_reset(struct lttng_ust_lib_ring_buffer_backend *buf */ void channel_backend_reset(struct channel_backend *chanb) { - struct channel *chan = caa_container_of(chanb, struct channel, backend); + struct lttng_ust_lib_ring_buffer_channel *chan = caa_container_of(chanb, + struct lttng_ust_lib_ring_buffer_channel, backend); const struct lttng_ust_lib_ring_buffer_config *config = &chanb->config; /* @@ -260,7 +263,8 @@ int channel_backend_init(struct channel_backend *chanb, struct lttng_ust_shm_handle *handle, const int *stream_fds) { - struct channel *chan = caa_container_of(chanb, struct channel, backend); + struct lttng_ust_lib_ring_buffer_channel *chan = caa_container_of(chanb, + struct lttng_ust_lib_ring_buffer_channel, backend); unsigned int i; int ret; size_t shmsize = 0, num_subbuf_alloc; @@ -269,7 +273,7 @@ int channel_backend_init(struct channel_backend *chanb, if (!name) return -EPERM; - page_size = sysconf(_SC_PAGE_SIZE); + page_size = LTTNG_UST_PAGE_SIZE; if (page_size <= 0) { return -ENOMEM; } @@ -309,25 +313,29 @@ int channel_backend_init(struct channel_backend *chanb, memcpy(&chanb->config, config, sizeof(*config)); /* Per-cpu buffer size: control (prior to backend) */ - shmsize = offset_align(shmsize, __alignof__(struct lttng_ust_lib_ring_buffer)); + shmsize = lttng_ust_offset_align(shmsize, __alignof__(struct lttng_ust_lib_ring_buffer)); shmsize += sizeof(struct lttng_ust_lib_ring_buffer); + shmsize += lttng_ust_offset_align(shmsize, __alignof__(struct commit_counters_hot)); + shmsize += sizeof(struct commit_counters_hot) * num_subbuf; + shmsize += lttng_ust_offset_align(shmsize, __alignof__(struct commit_counters_cold)); + shmsize += sizeof(struct commit_counters_cold) * num_subbuf; + /* Sampled timestamp end */ + shmsize += lttng_ust_offset_align(shmsize, __alignof__(uint64_t)); + shmsize += sizeof(uint64_t) * num_subbuf; /* Per-cpu buffer size: backend */ /* num_subbuf + 1 is the worse case */ num_subbuf_alloc = num_subbuf + 1; - shmsize += offset_align(shmsize, __alignof__(struct lttng_ust_lib_ring_buffer_backend_pages_shmp)); + shmsize += lttng_ust_offset_align(shmsize, __alignof__(struct lttng_ust_lib_ring_buffer_backend_pages_shmp)); shmsize += sizeof(struct lttng_ust_lib_ring_buffer_backend_pages_shmp) * num_subbuf_alloc; - shmsize += offset_align(shmsize, page_size); + shmsize += lttng_ust_offset_align(shmsize, page_size); shmsize += subbuf_size * num_subbuf_alloc; - shmsize += offset_align(shmsize, __alignof__(struct lttng_ust_lib_ring_buffer_backend_pages)); + shmsize += lttng_ust_offset_align(shmsize, __alignof__(struct lttng_ust_lib_ring_buffer_backend_pages)); shmsize += sizeof(struct lttng_ust_lib_ring_buffer_backend_pages) * num_subbuf_alloc; - shmsize += offset_align(shmsize, __alignof__(struct lttng_ust_lib_ring_buffer_backend_subbuffer)); + shmsize += lttng_ust_offset_align(shmsize, __alignof__(struct lttng_ust_lib_ring_buffer_backend_subbuffer)); shmsize += sizeof(struct lttng_ust_lib_ring_buffer_backend_subbuffer) * num_subbuf; - /* Per-cpu buffer size: control (after backend) */ - shmsize += offset_align(shmsize, __alignof__(struct commit_counters_hot)); - shmsize += sizeof(struct commit_counters_hot) * num_subbuf; - shmsize += offset_align(shmsize, __alignof__(struct commit_counters_cold)); - shmsize += sizeof(struct commit_counters_cold) * num_subbuf; + shmsize += lttng_ust_offset_align(shmsize, __alignof__(struct lttng_ust_lib_ring_buffer_backend_counts)); + shmsize += sizeof(struct lttng_ust_lib_ring_buffer_backend_counts) * num_subbuf; if (config->alloc == RING_BUFFER_ALLOC_PER_CPU) { struct lttng_ust_lib_ring_buffer *buf; @@ -338,7 +346,7 @@ int channel_backend_init(struct channel_backend *chanb, struct shm_object *shmobj; shmobj = shm_object_table_alloc(handle->table, shmsize, - SHM_OBJECT_SHM, stream_fds[i]); + SHM_OBJECT_SHM, stream_fds[i], i); if (!shmobj) goto end; align_shm(shmobj, __alignof__(struct lttng_ust_lib_ring_buffer)); @@ -357,7 +365,7 @@ int channel_backend_init(struct channel_backend *chanb, struct lttng_ust_lib_ring_buffer *buf; shmobj = shm_object_table_alloc(handle->table, shmsize, - SHM_OBJECT_SHM, stream_fds[0]); + SHM_OBJECT_SHM, stream_fds[0], -1); if (!shmobj) goto end; align_shm(shmobj, __alignof__(struct lttng_ust_lib_ring_buffer)); @@ -387,8 +395,8 @@ end: * * Destroy all channel buffers and frees the channel. */ -void channel_backend_free(struct channel_backend *chanb, - struct lttng_ust_shm_handle *handle) +void channel_backend_free(struct channel_backend *chanb __attribute__((unused)), + struct lttng_ust_shm_handle *handle __attribute__((unused))) { /* SHM teardown takes care of everything */ } @@ -410,6 +418,7 @@ size_t lib_ring_buffer_read(struct lttng_ust_lib_ring_buffer_backend *bufb, size const struct lttng_ust_lib_ring_buffer_config *config; ssize_t orig_len; struct lttng_ust_lib_ring_buffer_backend_pages_shmp *rpages; + struct lttng_ust_lib_ring_buffer_backend_pages *backend_pages; unsigned long sb_bindex, id; void *src; @@ -425,6 +434,8 @@ size_t lib_ring_buffer_read(struct lttng_ust_lib_ring_buffer_backend *bufb, size id = bufb->buf_rsb.id; sb_bindex = subbuffer_id_get_index(config, id); rpages = shmp_index(handle, bufb->array, sb_bindex); + if (!rpages) + return 0; /* * Underlying layer should never ask for reads across * subbuffers. @@ -432,8 +443,10 @@ size_t lib_ring_buffer_read(struct lttng_ust_lib_ring_buffer_backend *bufb, size CHAN_WARN_ON(chanb, offset >= chanb->buf_size); CHAN_WARN_ON(chanb, config->mode == RING_BUFFER_OVERWRITE && subbuffer_id_is_noref(config, id)); - src = shmp_index(handle, shmp(handle, rpages->shmp)->p, - offset & (chanb->subbuf_size - 1)); + backend_pages = shmp(handle, rpages->shmp); + if (!backend_pages) + return 0; + src = shmp_index(handle, backend_pages->p, offset & (chanb->subbuf_size - 1)); if (caa_unlikely(!src)) return 0; memcpy(dest, src, len); @@ -459,6 +472,7 @@ int lib_ring_buffer_read_cstr(struct lttng_ust_lib_ring_buffer_backend *bufb, si ssize_t string_len, orig_offset; char *str; struct lttng_ust_lib_ring_buffer_backend_pages_shmp *rpages; + struct lttng_ust_lib_ring_buffer_backend_pages *backend_pages; unsigned long sb_bindex, id; chanb = &shmp(handle, bufb->chan)->backend; @@ -472,6 +486,8 @@ int lib_ring_buffer_read_cstr(struct lttng_ust_lib_ring_buffer_backend *bufb, si id = bufb->buf_rsb.id; sb_bindex = subbuffer_id_get_index(config, id); rpages = shmp_index(handle, bufb->array, sb_bindex); + if (!rpages) + return -EINVAL; /* * Underlying layer should never ask for reads across * subbuffers. @@ -479,7 +495,10 @@ int lib_ring_buffer_read_cstr(struct lttng_ust_lib_ring_buffer_backend *bufb, si CHAN_WARN_ON(chanb, offset >= chanb->buf_size); CHAN_WARN_ON(chanb, config->mode == RING_BUFFER_OVERWRITE && subbuffer_id_is_noref(config, id)); - str = shmp_index(handle, shmp(handle, rpages->shmp)->p, offset & (chanb->subbuf_size - 1)); + backend_pages = shmp(handle, rpages->shmp); + if (!backend_pages) + return -EINVAL; + str = shmp_index(handle, backend_pages->p, offset & (chanb->subbuf_size - 1)); if (caa_unlikely(!str)) return -EINVAL; string_len = strnlen(str, len); @@ -506,6 +525,7 @@ void *lib_ring_buffer_read_offset_address(struct lttng_ust_lib_ring_buffer_backe struct lttng_ust_shm_handle *handle) { struct lttng_ust_lib_ring_buffer_backend_pages_shmp *rpages; + struct lttng_ust_lib_ring_buffer_backend_pages *backend_pages; struct channel_backend *chanb; const struct lttng_ust_lib_ring_buffer_config *config; unsigned long sb_bindex, id; @@ -518,9 +538,14 @@ void *lib_ring_buffer_read_offset_address(struct lttng_ust_lib_ring_buffer_backe id = bufb->buf_rsb.id; sb_bindex = subbuffer_id_get_index(config, id); rpages = shmp_index(handle, bufb->array, sb_bindex); + if (!rpages) + return NULL; CHAN_WARN_ON(chanb, config->mode == RING_BUFFER_OVERWRITE && subbuffer_id_is_noref(config, id)); - return shmp_index(handle, shmp(handle, rpages->shmp)->p, offset & (chanb->subbuf_size - 1)); + backend_pages = shmp(handle, rpages->shmp); + if (!backend_pages) + return NULL; + return shmp_index(handle, backend_pages->p, offset & (chanb->subbuf_size - 1)); } /** @@ -539,6 +564,7 @@ void *lib_ring_buffer_offset_address(struct lttng_ust_lib_ring_buffer_backend *b { size_t sbidx; struct lttng_ust_lib_ring_buffer_backend_pages_shmp *rpages; + struct lttng_ust_lib_ring_buffer_backend_pages *backend_pages; struct channel_backend *chanb; const struct lttng_ust_lib_ring_buffer_config *config; unsigned long sb_bindex, id; @@ -556,7 +582,12 @@ void *lib_ring_buffer_offset_address(struct lttng_ust_lib_ring_buffer_backend *b id = sb->id; sb_bindex = subbuffer_id_get_index(config, id); rpages = shmp_index(handle, bufb->array, sb_bindex); + if (!rpages) + return NULL; CHAN_WARN_ON(chanb, config->mode == RING_BUFFER_OVERWRITE && subbuffer_id_is_noref(config, id)); - return shmp_index(handle, shmp(handle, rpages->shmp)->p, offset & (chanb->subbuf_size - 1)); + backend_pages = shmp(handle, rpages->shmp); + if (!backend_pages) + return NULL; + return shmp_index(handle, backend_pages->p, offset & (chanb->subbuf_size - 1)); }