1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright (C) 2012-2018 Rob Clark <robclark@freedesktop.org> 3bf215546Sopenharmony_ci * 4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 5bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 6bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 7bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 9bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 10bf215546Sopenharmony_ci * 11bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next 12bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the 13bf215546Sopenharmony_ci * Software. 14bf215546Sopenharmony_ci * 15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20bf215546Sopenharmony_ci * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21bf215546Sopenharmony_ci * SOFTWARE. 22bf215546Sopenharmony_ci * 23bf215546Sopenharmony_ci * Authors: 24bf215546Sopenharmony_ci * Rob Clark <robclark@freedesktop.org> 25bf215546Sopenharmony_ci */ 26bf215546Sopenharmony_ci 27bf215546Sopenharmony_ci#include <assert.h> 28bf215546Sopenharmony_ci#include <inttypes.h> 29bf215546Sopenharmony_ci 30bf215546Sopenharmony_ci#include "util/hash_table.h" 31bf215546Sopenharmony_ci#include "util/set.h" 32bf215546Sopenharmony_ci#include "util/slab.h" 33bf215546Sopenharmony_ci 34bf215546Sopenharmony_ci#include "drm/freedreno_ringbuffer.h" 35bf215546Sopenharmony_ci#include "msm_priv.h" 36bf215546Sopenharmony_ci 37bf215546Sopenharmony_ci/* The legacy implementation of submit/ringbuffer, which still does the 38bf215546Sopenharmony_ci * traditional reloc and cmd tracking 39bf215546Sopenharmony_ci */ 40bf215546Sopenharmony_ci 41bf215546Sopenharmony_ci#define INIT_SIZE 0x1000 42bf215546Sopenharmony_ci 43bf215546Sopenharmony_cistruct msm_submit { 44bf215546Sopenharmony_ci struct fd_submit base; 45bf215546Sopenharmony_ci 46bf215546Sopenharmony_ci DECLARE_ARRAY(struct drm_msm_gem_submit_bo, submit_bos); 47bf215546Sopenharmony_ci DECLARE_ARRAY(struct fd_bo *, bos); 48bf215546Sopenharmony_ci 49bf215546Sopenharmony_ci /* maps fd_bo to idx in bos table: */ 50bf215546Sopenharmony_ci struct hash_table *bo_table; 51bf215546Sopenharmony_ci 52bf215546Sopenharmony_ci struct slab_mempool ring_pool; 53bf215546Sopenharmony_ci 54bf215546Sopenharmony_ci /* hash-set of associated rings: */ 55bf215546Sopenharmony_ci struct set *ring_set; 56bf215546Sopenharmony_ci 57bf215546Sopenharmony_ci /* Allow for sub-allocation of stateobj ring buffers (ie. sharing 58bf215546Sopenharmony_ci * the same underlying bo).. 59bf215546Sopenharmony_ci * 60bf215546Sopenharmony_ci * We also rely on previous stateobj having been fully constructed 61bf215546Sopenharmony_ci * so we can reclaim extra space at it's end. 62bf215546Sopenharmony_ci */ 63bf215546Sopenharmony_ci struct fd_ringbuffer *suballoc_ring; 64bf215546Sopenharmony_ci}; 65bf215546Sopenharmony_ciFD_DEFINE_CAST(fd_submit, msm_submit); 66bf215546Sopenharmony_ci 67bf215546Sopenharmony_ci/* for FD_RINGBUFFER_GROWABLE rb's, tracks the 'finalized' cmdstream buffers 68bf215546Sopenharmony_ci * and sizes. Ie. a finalized buffer can have no more commands appended to 69bf215546Sopenharmony_ci * it. 70bf215546Sopenharmony_ci */ 71bf215546Sopenharmony_cistruct msm_cmd { 72bf215546Sopenharmony_ci struct fd_bo *ring_bo; 73bf215546Sopenharmony_ci unsigned size; 74bf215546Sopenharmony_ci DECLARE_ARRAY(struct drm_msm_gem_submit_reloc, relocs); 75bf215546Sopenharmony_ci}; 76bf215546Sopenharmony_ci 77bf215546Sopenharmony_cistatic struct msm_cmd * 78bf215546Sopenharmony_cicmd_new(struct fd_bo *ring_bo) 79bf215546Sopenharmony_ci{ 80bf215546Sopenharmony_ci struct msm_cmd *cmd = malloc(sizeof(*cmd)); 81bf215546Sopenharmony_ci cmd->ring_bo = fd_bo_ref(ring_bo); 82bf215546Sopenharmony_ci cmd->size = 0; 83bf215546Sopenharmony_ci cmd->nr_relocs = cmd->max_relocs = 0; 84bf215546Sopenharmony_ci cmd->relocs = NULL; 85bf215546Sopenharmony_ci return cmd; 86bf215546Sopenharmony_ci} 87bf215546Sopenharmony_ci 88bf215546Sopenharmony_cistatic void 89bf215546Sopenharmony_cicmd_free(struct msm_cmd *cmd) 90bf215546Sopenharmony_ci{ 91bf215546Sopenharmony_ci fd_bo_del(cmd->ring_bo); 92bf215546Sopenharmony_ci free(cmd->relocs); 93bf215546Sopenharmony_ci free(cmd); 94bf215546Sopenharmony_ci} 95bf215546Sopenharmony_ci 96bf215546Sopenharmony_cistruct msm_ringbuffer { 97bf215546Sopenharmony_ci struct fd_ringbuffer base; 98bf215546Sopenharmony_ci 99bf215546Sopenharmony_ci /* for FD_RINGBUFFER_STREAMING rb's which are sub-allocated */ 100bf215546Sopenharmony_ci unsigned offset; 101bf215546Sopenharmony_ci 102bf215546Sopenharmony_ci union { 103bf215546Sopenharmony_ci /* for _FD_RINGBUFFER_OBJECT case: */ 104bf215546Sopenharmony_ci struct { 105bf215546Sopenharmony_ci struct fd_pipe *pipe; 106bf215546Sopenharmony_ci DECLARE_ARRAY(struct fd_bo *, reloc_bos); 107bf215546Sopenharmony_ci struct set *ring_set; 108bf215546Sopenharmony_ci }; 109bf215546Sopenharmony_ci /* for other cases: */ 110bf215546Sopenharmony_ci struct { 111bf215546Sopenharmony_ci struct fd_submit *submit; 112bf215546Sopenharmony_ci DECLARE_ARRAY(struct msm_cmd *, cmds); 113bf215546Sopenharmony_ci }; 114bf215546Sopenharmony_ci } u; 115bf215546Sopenharmony_ci 116bf215546Sopenharmony_ci struct msm_cmd *cmd; /* current cmd */ 117bf215546Sopenharmony_ci struct fd_bo *ring_bo; 118bf215546Sopenharmony_ci}; 119bf215546Sopenharmony_ciFD_DEFINE_CAST(fd_ringbuffer, msm_ringbuffer); 120bf215546Sopenharmony_ci 121bf215546Sopenharmony_cistatic void finalize_current_cmd(struct fd_ringbuffer *ring); 122bf215546Sopenharmony_cistatic struct fd_ringbuffer * 123bf215546Sopenharmony_cimsm_ringbuffer_init(struct msm_ringbuffer *msm_ring, uint32_t size, 124bf215546Sopenharmony_ci enum fd_ringbuffer_flags flags); 125bf215546Sopenharmony_ci 126bf215546Sopenharmony_ci/* add (if needed) bo to submit and return index: */ 127bf215546Sopenharmony_cistatic uint32_t 128bf215546Sopenharmony_ciappend_bo(struct msm_submit *submit, struct fd_bo *bo) 129bf215546Sopenharmony_ci{ 130bf215546Sopenharmony_ci uint32_t idx; 131bf215546Sopenharmony_ci 132bf215546Sopenharmony_ci /* NOTE: it is legal to use the same bo on different threads for 133bf215546Sopenharmony_ci * different submits. But it is not legal to use the same submit 134bf215546Sopenharmony_ci * from given threads. 135bf215546Sopenharmony_ci */ 136bf215546Sopenharmony_ci idx = READ_ONCE(bo->idx); 137bf215546Sopenharmony_ci 138bf215546Sopenharmony_ci if (unlikely((idx >= submit->nr_submit_bos) || 139bf215546Sopenharmony_ci (submit->submit_bos[idx].handle != bo->handle))) { 140bf215546Sopenharmony_ci uint32_t hash = _mesa_hash_pointer(bo); 141bf215546Sopenharmony_ci struct hash_entry *entry; 142bf215546Sopenharmony_ci 143bf215546Sopenharmony_ci entry = _mesa_hash_table_search_pre_hashed(submit->bo_table, hash, bo); 144bf215546Sopenharmony_ci if (entry) { 145bf215546Sopenharmony_ci /* found */ 146bf215546Sopenharmony_ci idx = (uint32_t)(uintptr_t)entry->data; 147bf215546Sopenharmony_ci } else { 148bf215546Sopenharmony_ci idx = APPEND( 149bf215546Sopenharmony_ci submit, submit_bos, 150bf215546Sopenharmony_ci (struct drm_msm_gem_submit_bo){ 151bf215546Sopenharmony_ci .flags = bo->reloc_flags & (MSM_SUBMIT_BO_READ | MSM_SUBMIT_BO_WRITE), 152bf215546Sopenharmony_ci .handle = bo->handle, 153bf215546Sopenharmony_ci .presumed = 0, 154bf215546Sopenharmony_ci }); 155bf215546Sopenharmony_ci APPEND(submit, bos, fd_bo_ref(bo)); 156bf215546Sopenharmony_ci 157bf215546Sopenharmony_ci _mesa_hash_table_insert_pre_hashed(submit->bo_table, hash, bo, 158bf215546Sopenharmony_ci (void *)(uintptr_t)idx); 159bf215546Sopenharmony_ci } 160bf215546Sopenharmony_ci bo->idx = idx; 161bf215546Sopenharmony_ci } 162bf215546Sopenharmony_ci 163bf215546Sopenharmony_ci return idx; 164bf215546Sopenharmony_ci} 165bf215546Sopenharmony_ci 166bf215546Sopenharmony_cistatic void 167bf215546Sopenharmony_ciappend_ring(struct set *set, struct fd_ringbuffer *ring) 168bf215546Sopenharmony_ci{ 169bf215546Sopenharmony_ci uint32_t hash = _mesa_hash_pointer(ring); 170bf215546Sopenharmony_ci 171bf215546Sopenharmony_ci if (!_mesa_set_search_pre_hashed(set, hash, ring)) { 172bf215546Sopenharmony_ci fd_ringbuffer_ref(ring); 173bf215546Sopenharmony_ci _mesa_set_add_pre_hashed(set, hash, ring); 174bf215546Sopenharmony_ci } 175bf215546Sopenharmony_ci} 176bf215546Sopenharmony_ci 177bf215546Sopenharmony_cistatic void 178bf215546Sopenharmony_cimsm_submit_suballoc_ring_bo(struct fd_submit *submit, 179bf215546Sopenharmony_ci struct msm_ringbuffer *msm_ring, uint32_t size) 180bf215546Sopenharmony_ci{ 181bf215546Sopenharmony_ci struct msm_submit *msm_submit = to_msm_submit(submit); 182bf215546Sopenharmony_ci unsigned suballoc_offset = 0; 183bf215546Sopenharmony_ci struct fd_bo *suballoc_bo = NULL; 184bf215546Sopenharmony_ci 185bf215546Sopenharmony_ci if (msm_submit->suballoc_ring) { 186bf215546Sopenharmony_ci struct msm_ringbuffer *suballoc_ring = 187bf215546Sopenharmony_ci to_msm_ringbuffer(msm_submit->suballoc_ring); 188bf215546Sopenharmony_ci 189bf215546Sopenharmony_ci suballoc_bo = suballoc_ring->ring_bo; 190bf215546Sopenharmony_ci suballoc_offset = 191bf215546Sopenharmony_ci fd_ringbuffer_size(msm_submit->suballoc_ring) + suballoc_ring->offset; 192bf215546Sopenharmony_ci 193bf215546Sopenharmony_ci suballoc_offset = align(suballoc_offset, 0x10); 194bf215546Sopenharmony_ci 195bf215546Sopenharmony_ci if ((size + suballoc_offset) > suballoc_bo->size) { 196bf215546Sopenharmony_ci suballoc_bo = NULL; 197bf215546Sopenharmony_ci } 198bf215546Sopenharmony_ci } 199bf215546Sopenharmony_ci 200bf215546Sopenharmony_ci if (!suballoc_bo) { 201bf215546Sopenharmony_ci // TODO possibly larger size for streaming bo? 202bf215546Sopenharmony_ci msm_ring->ring_bo = fd_bo_new_ring(submit->pipe->dev, 0x8000); 203bf215546Sopenharmony_ci msm_ring->offset = 0; 204bf215546Sopenharmony_ci } else { 205bf215546Sopenharmony_ci msm_ring->ring_bo = fd_bo_ref(suballoc_bo); 206bf215546Sopenharmony_ci msm_ring->offset = suballoc_offset; 207bf215546Sopenharmony_ci } 208bf215546Sopenharmony_ci 209bf215546Sopenharmony_ci struct fd_ringbuffer *old_suballoc_ring = msm_submit->suballoc_ring; 210bf215546Sopenharmony_ci 211bf215546Sopenharmony_ci msm_submit->suballoc_ring = fd_ringbuffer_ref(&msm_ring->base); 212bf215546Sopenharmony_ci 213bf215546Sopenharmony_ci if (old_suballoc_ring) 214bf215546Sopenharmony_ci fd_ringbuffer_del(old_suballoc_ring); 215bf215546Sopenharmony_ci} 216bf215546Sopenharmony_ci 217bf215546Sopenharmony_cistatic struct fd_ringbuffer * 218bf215546Sopenharmony_cimsm_submit_new_ringbuffer(struct fd_submit *submit, uint32_t size, 219bf215546Sopenharmony_ci enum fd_ringbuffer_flags flags) 220bf215546Sopenharmony_ci{ 221bf215546Sopenharmony_ci struct msm_submit *msm_submit = to_msm_submit(submit); 222bf215546Sopenharmony_ci struct msm_ringbuffer *msm_ring; 223bf215546Sopenharmony_ci 224bf215546Sopenharmony_ci msm_ring = slab_alloc_st(&msm_submit->ring_pool); 225bf215546Sopenharmony_ci 226bf215546Sopenharmony_ci msm_ring->u.submit = submit; 227bf215546Sopenharmony_ci 228bf215546Sopenharmony_ci /* NOTE: needs to be before _suballoc_ring_bo() since it could 229bf215546Sopenharmony_ci * increment the refcnt of the current ring 230bf215546Sopenharmony_ci */ 231bf215546Sopenharmony_ci msm_ring->base.refcnt = 1; 232bf215546Sopenharmony_ci 233bf215546Sopenharmony_ci if (flags & FD_RINGBUFFER_STREAMING) { 234bf215546Sopenharmony_ci msm_submit_suballoc_ring_bo(submit, msm_ring, size); 235bf215546Sopenharmony_ci } else { 236bf215546Sopenharmony_ci if (flags & FD_RINGBUFFER_GROWABLE) 237bf215546Sopenharmony_ci size = INIT_SIZE; 238bf215546Sopenharmony_ci 239bf215546Sopenharmony_ci msm_ring->offset = 0; 240bf215546Sopenharmony_ci msm_ring->ring_bo = fd_bo_new_ring(submit->pipe->dev, size); 241bf215546Sopenharmony_ci } 242bf215546Sopenharmony_ci 243bf215546Sopenharmony_ci if (!msm_ringbuffer_init(msm_ring, size, flags)) 244bf215546Sopenharmony_ci return NULL; 245bf215546Sopenharmony_ci 246bf215546Sopenharmony_ci return &msm_ring->base; 247bf215546Sopenharmony_ci} 248bf215546Sopenharmony_ci 249bf215546Sopenharmony_cistatic struct drm_msm_gem_submit_reloc * 250bf215546Sopenharmony_cihandle_stateobj_relocs(struct msm_submit *submit, struct msm_ringbuffer *ring) 251bf215546Sopenharmony_ci{ 252bf215546Sopenharmony_ci struct msm_cmd *cmd = ring->cmd; 253bf215546Sopenharmony_ci struct drm_msm_gem_submit_reloc *relocs; 254bf215546Sopenharmony_ci 255bf215546Sopenharmony_ci relocs = malloc(cmd->nr_relocs * sizeof(*relocs)); 256bf215546Sopenharmony_ci 257bf215546Sopenharmony_ci for (unsigned i = 0; i < cmd->nr_relocs; i++) { 258bf215546Sopenharmony_ci unsigned idx = cmd->relocs[i].reloc_idx; 259bf215546Sopenharmony_ci struct fd_bo *bo = ring->u.reloc_bos[idx]; 260bf215546Sopenharmony_ci 261bf215546Sopenharmony_ci relocs[i] = cmd->relocs[i]; 262bf215546Sopenharmony_ci relocs[i].reloc_idx = append_bo(submit, bo); 263bf215546Sopenharmony_ci } 264bf215546Sopenharmony_ci 265bf215546Sopenharmony_ci return relocs; 266bf215546Sopenharmony_ci} 267bf215546Sopenharmony_ci 268bf215546Sopenharmony_cistatic int 269bf215546Sopenharmony_cimsm_submit_flush(struct fd_submit *submit, int in_fence_fd, 270bf215546Sopenharmony_ci struct fd_submit_fence *out_fence) 271bf215546Sopenharmony_ci{ 272bf215546Sopenharmony_ci struct msm_submit *msm_submit = to_msm_submit(submit); 273bf215546Sopenharmony_ci struct msm_pipe *msm_pipe = to_msm_pipe(submit->pipe); 274bf215546Sopenharmony_ci struct drm_msm_gem_submit req = { 275bf215546Sopenharmony_ci .flags = msm_pipe->pipe, 276bf215546Sopenharmony_ci .queueid = msm_pipe->queue_id, 277bf215546Sopenharmony_ci }; 278bf215546Sopenharmony_ci int ret; 279bf215546Sopenharmony_ci 280bf215546Sopenharmony_ci finalize_current_cmd(submit->primary); 281bf215546Sopenharmony_ci append_ring(msm_submit->ring_set, submit->primary); 282bf215546Sopenharmony_ci 283bf215546Sopenharmony_ci unsigned nr_cmds = 0; 284bf215546Sopenharmony_ci unsigned nr_objs = 0; 285bf215546Sopenharmony_ci 286bf215546Sopenharmony_ci set_foreach (msm_submit->ring_set, entry) { 287bf215546Sopenharmony_ci struct fd_ringbuffer *ring = (void *)entry->key; 288bf215546Sopenharmony_ci if (ring->flags & _FD_RINGBUFFER_OBJECT) { 289bf215546Sopenharmony_ci nr_cmds += 1; 290bf215546Sopenharmony_ci nr_objs += 1; 291bf215546Sopenharmony_ci } else { 292bf215546Sopenharmony_ci if (ring != submit->primary) 293bf215546Sopenharmony_ci finalize_current_cmd(ring); 294bf215546Sopenharmony_ci nr_cmds += to_msm_ringbuffer(ring)->u.nr_cmds; 295bf215546Sopenharmony_ci } 296bf215546Sopenharmony_ci } 297bf215546Sopenharmony_ci 298bf215546Sopenharmony_ci void *obj_relocs[nr_objs]; 299bf215546Sopenharmony_ci struct drm_msm_gem_submit_cmd cmds[nr_cmds]; 300bf215546Sopenharmony_ci unsigned i = 0, o = 0; 301bf215546Sopenharmony_ci 302bf215546Sopenharmony_ci set_foreach (msm_submit->ring_set, entry) { 303bf215546Sopenharmony_ci struct fd_ringbuffer *ring = (void *)entry->key; 304bf215546Sopenharmony_ci struct msm_ringbuffer *msm_ring = to_msm_ringbuffer(ring); 305bf215546Sopenharmony_ci 306bf215546Sopenharmony_ci assert(i < nr_cmds); 307bf215546Sopenharmony_ci 308bf215546Sopenharmony_ci // TODO handle relocs: 309bf215546Sopenharmony_ci if (ring->flags & _FD_RINGBUFFER_OBJECT) { 310bf215546Sopenharmony_ci 311bf215546Sopenharmony_ci assert(o < nr_objs); 312bf215546Sopenharmony_ci 313bf215546Sopenharmony_ci void *relocs = handle_stateobj_relocs(msm_submit, msm_ring); 314bf215546Sopenharmony_ci obj_relocs[o++] = relocs; 315bf215546Sopenharmony_ci 316bf215546Sopenharmony_ci cmds[i].type = MSM_SUBMIT_CMD_IB_TARGET_BUF; 317bf215546Sopenharmony_ci cmds[i].submit_idx = append_bo(msm_submit, msm_ring->ring_bo); 318bf215546Sopenharmony_ci cmds[i].submit_offset = msm_ring->offset; 319bf215546Sopenharmony_ci cmds[i].size = offset_bytes(ring->cur, ring->start); 320bf215546Sopenharmony_ci cmds[i].pad = 0; 321bf215546Sopenharmony_ci cmds[i].nr_relocs = msm_ring->cmd->nr_relocs; 322bf215546Sopenharmony_ci cmds[i].relocs = VOID2U64(relocs); 323bf215546Sopenharmony_ci 324bf215546Sopenharmony_ci i++; 325bf215546Sopenharmony_ci } else { 326bf215546Sopenharmony_ci for (unsigned j = 0; j < msm_ring->u.nr_cmds; j++) { 327bf215546Sopenharmony_ci if (ring->flags & FD_RINGBUFFER_PRIMARY) { 328bf215546Sopenharmony_ci cmds[i].type = MSM_SUBMIT_CMD_BUF; 329bf215546Sopenharmony_ci } else { 330bf215546Sopenharmony_ci cmds[i].type = MSM_SUBMIT_CMD_IB_TARGET_BUF; 331bf215546Sopenharmony_ci } 332bf215546Sopenharmony_ci cmds[i].submit_idx = 333bf215546Sopenharmony_ci append_bo(msm_submit, msm_ring->u.cmds[j]->ring_bo); 334bf215546Sopenharmony_ci cmds[i].submit_offset = msm_ring->offset; 335bf215546Sopenharmony_ci cmds[i].size = msm_ring->u.cmds[j]->size; 336bf215546Sopenharmony_ci cmds[i].pad = 0; 337bf215546Sopenharmony_ci cmds[i].nr_relocs = msm_ring->u.cmds[j]->nr_relocs; 338bf215546Sopenharmony_ci cmds[i].relocs = VOID2U64(msm_ring->u.cmds[j]->relocs); 339bf215546Sopenharmony_ci 340bf215546Sopenharmony_ci i++; 341bf215546Sopenharmony_ci } 342bf215546Sopenharmony_ci } 343bf215546Sopenharmony_ci } 344bf215546Sopenharmony_ci 345bf215546Sopenharmony_ci simple_mtx_lock(&table_lock); 346bf215546Sopenharmony_ci for (unsigned j = 0; j < msm_submit->nr_bos; j++) { 347bf215546Sopenharmony_ci fd_bo_add_fence(msm_submit->bos[j], submit->pipe, submit->fence); 348bf215546Sopenharmony_ci } 349bf215546Sopenharmony_ci simple_mtx_unlock(&table_lock); 350bf215546Sopenharmony_ci 351bf215546Sopenharmony_ci if (in_fence_fd != -1) { 352bf215546Sopenharmony_ci req.flags |= MSM_SUBMIT_FENCE_FD_IN | MSM_SUBMIT_NO_IMPLICIT; 353bf215546Sopenharmony_ci req.fence_fd = in_fence_fd; 354bf215546Sopenharmony_ci } 355bf215546Sopenharmony_ci 356bf215546Sopenharmony_ci if (out_fence && out_fence->use_fence_fd) { 357bf215546Sopenharmony_ci req.flags |= MSM_SUBMIT_FENCE_FD_OUT; 358bf215546Sopenharmony_ci } 359bf215546Sopenharmony_ci 360bf215546Sopenharmony_ci /* needs to be after get_cmd() as that could create bos/cmds table: */ 361bf215546Sopenharmony_ci req.bos = VOID2U64(msm_submit->submit_bos), 362bf215546Sopenharmony_ci req.nr_bos = msm_submit->nr_submit_bos; 363bf215546Sopenharmony_ci req.cmds = VOID2U64(cmds), req.nr_cmds = nr_cmds; 364bf215546Sopenharmony_ci 365bf215546Sopenharmony_ci DEBUG_MSG("nr_cmds=%u, nr_bos=%u", req.nr_cmds, req.nr_bos); 366bf215546Sopenharmony_ci 367bf215546Sopenharmony_ci ret = drmCommandWriteRead(submit->pipe->dev->fd, DRM_MSM_GEM_SUBMIT, &req, 368bf215546Sopenharmony_ci sizeof(req)); 369bf215546Sopenharmony_ci if (ret) { 370bf215546Sopenharmony_ci ERROR_MSG("submit failed: %d (%s)", ret, strerror(errno)); 371bf215546Sopenharmony_ci msm_dump_submit(&req); 372bf215546Sopenharmony_ci } else if (!ret && out_fence) { 373bf215546Sopenharmony_ci out_fence->fence.kfence = req.fence; 374bf215546Sopenharmony_ci out_fence->fence.ufence = submit->fence; 375bf215546Sopenharmony_ci out_fence->fence_fd = req.fence_fd; 376bf215546Sopenharmony_ci } 377bf215546Sopenharmony_ci 378bf215546Sopenharmony_ci for (unsigned o = 0; o < nr_objs; o++) 379bf215546Sopenharmony_ci free(obj_relocs[o]); 380bf215546Sopenharmony_ci 381bf215546Sopenharmony_ci return ret; 382bf215546Sopenharmony_ci} 383bf215546Sopenharmony_ci 384bf215546Sopenharmony_cistatic void 385bf215546Sopenharmony_ciunref_rings(struct set_entry *entry) 386bf215546Sopenharmony_ci{ 387bf215546Sopenharmony_ci struct fd_ringbuffer *ring = (void *)entry->key; 388bf215546Sopenharmony_ci fd_ringbuffer_del(ring); 389bf215546Sopenharmony_ci} 390bf215546Sopenharmony_ci 391bf215546Sopenharmony_cistatic void 392bf215546Sopenharmony_cimsm_submit_destroy(struct fd_submit *submit) 393bf215546Sopenharmony_ci{ 394bf215546Sopenharmony_ci struct msm_submit *msm_submit = to_msm_submit(submit); 395bf215546Sopenharmony_ci 396bf215546Sopenharmony_ci if (msm_submit->suballoc_ring) 397bf215546Sopenharmony_ci fd_ringbuffer_del(msm_submit->suballoc_ring); 398bf215546Sopenharmony_ci 399bf215546Sopenharmony_ci _mesa_hash_table_destroy(msm_submit->bo_table, NULL); 400bf215546Sopenharmony_ci _mesa_set_destroy(msm_submit->ring_set, unref_rings); 401bf215546Sopenharmony_ci 402bf215546Sopenharmony_ci // TODO it would be nice to have a way to assert() if all 403bf215546Sopenharmony_ci // rb's haven't been free'd back to the slab, because that is 404bf215546Sopenharmony_ci // an indication that we are leaking bo's 405bf215546Sopenharmony_ci slab_destroy(&msm_submit->ring_pool); 406bf215546Sopenharmony_ci 407bf215546Sopenharmony_ci for (unsigned i = 0; i < msm_submit->nr_bos; i++) 408bf215546Sopenharmony_ci fd_bo_del(msm_submit->bos[i]); 409bf215546Sopenharmony_ci 410bf215546Sopenharmony_ci free(msm_submit->submit_bos); 411bf215546Sopenharmony_ci free(msm_submit->bos); 412bf215546Sopenharmony_ci free(msm_submit); 413bf215546Sopenharmony_ci} 414bf215546Sopenharmony_ci 415bf215546Sopenharmony_cistatic const struct fd_submit_funcs submit_funcs = { 416bf215546Sopenharmony_ci .new_ringbuffer = msm_submit_new_ringbuffer, 417bf215546Sopenharmony_ci .flush = msm_submit_flush, 418bf215546Sopenharmony_ci .destroy = msm_submit_destroy, 419bf215546Sopenharmony_ci}; 420bf215546Sopenharmony_ci 421bf215546Sopenharmony_cistruct fd_submit * 422bf215546Sopenharmony_cimsm_submit_new(struct fd_pipe *pipe) 423bf215546Sopenharmony_ci{ 424bf215546Sopenharmony_ci struct msm_submit *msm_submit = calloc(1, sizeof(*msm_submit)); 425bf215546Sopenharmony_ci struct fd_submit *submit; 426bf215546Sopenharmony_ci 427bf215546Sopenharmony_ci msm_submit->bo_table = _mesa_hash_table_create(NULL, _mesa_hash_pointer, 428bf215546Sopenharmony_ci _mesa_key_pointer_equal); 429bf215546Sopenharmony_ci msm_submit->ring_set = 430bf215546Sopenharmony_ci _mesa_set_create(NULL, _mesa_hash_pointer, _mesa_key_pointer_equal); 431bf215546Sopenharmony_ci // TODO tune size: 432bf215546Sopenharmony_ci slab_create(&msm_submit->ring_pool, sizeof(struct msm_ringbuffer), 16); 433bf215546Sopenharmony_ci 434bf215546Sopenharmony_ci submit = &msm_submit->base; 435bf215546Sopenharmony_ci submit->funcs = &submit_funcs; 436bf215546Sopenharmony_ci 437bf215546Sopenharmony_ci return submit; 438bf215546Sopenharmony_ci} 439bf215546Sopenharmony_ci 440bf215546Sopenharmony_cistatic void 441bf215546Sopenharmony_cifinalize_current_cmd(struct fd_ringbuffer *ring) 442bf215546Sopenharmony_ci{ 443bf215546Sopenharmony_ci struct msm_ringbuffer *msm_ring = to_msm_ringbuffer(ring); 444bf215546Sopenharmony_ci 445bf215546Sopenharmony_ci assert(!(ring->flags & _FD_RINGBUFFER_OBJECT)); 446bf215546Sopenharmony_ci 447bf215546Sopenharmony_ci if (!msm_ring->cmd) 448bf215546Sopenharmony_ci return; 449bf215546Sopenharmony_ci 450bf215546Sopenharmony_ci assert(msm_ring->cmd->ring_bo == msm_ring->ring_bo); 451bf215546Sopenharmony_ci 452bf215546Sopenharmony_ci msm_ring->cmd->size = offset_bytes(ring->cur, ring->start); 453bf215546Sopenharmony_ci APPEND(&msm_ring->u, cmds, msm_ring->cmd); 454bf215546Sopenharmony_ci msm_ring->cmd = NULL; 455bf215546Sopenharmony_ci} 456bf215546Sopenharmony_ci 457bf215546Sopenharmony_cistatic void 458bf215546Sopenharmony_cimsm_ringbuffer_grow(struct fd_ringbuffer *ring, uint32_t size) 459bf215546Sopenharmony_ci{ 460bf215546Sopenharmony_ci struct msm_ringbuffer *msm_ring = to_msm_ringbuffer(ring); 461bf215546Sopenharmony_ci struct fd_pipe *pipe = msm_ring->u.submit->pipe; 462bf215546Sopenharmony_ci 463bf215546Sopenharmony_ci assert(ring->flags & FD_RINGBUFFER_GROWABLE); 464bf215546Sopenharmony_ci 465bf215546Sopenharmony_ci finalize_current_cmd(ring); 466bf215546Sopenharmony_ci 467bf215546Sopenharmony_ci fd_bo_del(msm_ring->ring_bo); 468bf215546Sopenharmony_ci msm_ring->ring_bo = fd_bo_new_ring(pipe->dev, size); 469bf215546Sopenharmony_ci msm_ring->cmd = cmd_new(msm_ring->ring_bo); 470bf215546Sopenharmony_ci 471bf215546Sopenharmony_ci ring->start = fd_bo_map(msm_ring->ring_bo); 472bf215546Sopenharmony_ci ring->end = &(ring->start[size / 4]); 473bf215546Sopenharmony_ci ring->cur = ring->start; 474bf215546Sopenharmony_ci ring->size = size; 475bf215546Sopenharmony_ci} 476bf215546Sopenharmony_ci 477bf215546Sopenharmony_cistatic void 478bf215546Sopenharmony_cimsm_ringbuffer_emit_reloc(struct fd_ringbuffer *ring, 479bf215546Sopenharmony_ci const struct fd_reloc *reloc) 480bf215546Sopenharmony_ci{ 481bf215546Sopenharmony_ci struct msm_ringbuffer *msm_ring = to_msm_ringbuffer(ring); 482bf215546Sopenharmony_ci struct fd_pipe *pipe; 483bf215546Sopenharmony_ci unsigned reloc_idx; 484bf215546Sopenharmony_ci 485bf215546Sopenharmony_ci if (ring->flags & _FD_RINGBUFFER_OBJECT) { 486bf215546Sopenharmony_ci unsigned idx = APPEND(&msm_ring->u, reloc_bos, fd_bo_ref(reloc->bo)); 487bf215546Sopenharmony_ci 488bf215546Sopenharmony_ci /* this gets fixed up at submit->flush() time, since this state- 489bf215546Sopenharmony_ci * object rb can be used with many different submits 490bf215546Sopenharmony_ci */ 491bf215546Sopenharmony_ci reloc_idx = idx; 492bf215546Sopenharmony_ci 493bf215546Sopenharmony_ci pipe = msm_ring->u.pipe; 494bf215546Sopenharmony_ci } else { 495bf215546Sopenharmony_ci struct msm_submit *msm_submit = to_msm_submit(msm_ring->u.submit); 496bf215546Sopenharmony_ci 497bf215546Sopenharmony_ci reloc_idx = append_bo(msm_submit, reloc->bo); 498bf215546Sopenharmony_ci 499bf215546Sopenharmony_ci pipe = msm_ring->u.submit->pipe; 500bf215546Sopenharmony_ci } 501bf215546Sopenharmony_ci 502bf215546Sopenharmony_ci APPEND(msm_ring->cmd, relocs, 503bf215546Sopenharmony_ci (struct drm_msm_gem_submit_reloc){ 504bf215546Sopenharmony_ci .reloc_idx = reloc_idx, 505bf215546Sopenharmony_ci .reloc_offset = reloc->offset, 506bf215546Sopenharmony_ci .or = reloc->orval, 507bf215546Sopenharmony_ci .shift = reloc->shift, 508bf215546Sopenharmony_ci .submit_offset = 509bf215546Sopenharmony_ci offset_bytes(ring->cur, ring->start) + msm_ring->offset, 510bf215546Sopenharmony_ci }); 511bf215546Sopenharmony_ci 512bf215546Sopenharmony_ci ring->cur++; 513bf215546Sopenharmony_ci 514bf215546Sopenharmony_ci if (fd_dev_64b(&pipe->dev_id)) { 515bf215546Sopenharmony_ci APPEND(msm_ring->cmd, relocs, 516bf215546Sopenharmony_ci (struct drm_msm_gem_submit_reloc){ 517bf215546Sopenharmony_ci .reloc_idx = reloc_idx, 518bf215546Sopenharmony_ci .reloc_offset = reloc->offset, 519bf215546Sopenharmony_ci .or = reloc->orval >> 32, 520bf215546Sopenharmony_ci .shift = reloc->shift - 32, 521bf215546Sopenharmony_ci .submit_offset = 522bf215546Sopenharmony_ci offset_bytes(ring->cur, ring->start) + msm_ring->offset, 523bf215546Sopenharmony_ci }); 524bf215546Sopenharmony_ci 525bf215546Sopenharmony_ci ring->cur++; 526bf215546Sopenharmony_ci } 527bf215546Sopenharmony_ci} 528bf215546Sopenharmony_ci 529bf215546Sopenharmony_cistatic void 530bf215546Sopenharmony_ciappend_stateobj_rings(struct msm_submit *submit, struct fd_ringbuffer *target) 531bf215546Sopenharmony_ci{ 532bf215546Sopenharmony_ci struct msm_ringbuffer *msm_target = to_msm_ringbuffer(target); 533bf215546Sopenharmony_ci 534bf215546Sopenharmony_ci assert(target->flags & _FD_RINGBUFFER_OBJECT); 535bf215546Sopenharmony_ci 536bf215546Sopenharmony_ci set_foreach (msm_target->u.ring_set, entry) { 537bf215546Sopenharmony_ci struct fd_ringbuffer *ring = (void *)entry->key; 538bf215546Sopenharmony_ci 539bf215546Sopenharmony_ci append_ring(submit->ring_set, ring); 540bf215546Sopenharmony_ci 541bf215546Sopenharmony_ci if (ring->flags & _FD_RINGBUFFER_OBJECT) { 542bf215546Sopenharmony_ci append_stateobj_rings(submit, ring); 543bf215546Sopenharmony_ci } 544bf215546Sopenharmony_ci } 545bf215546Sopenharmony_ci} 546bf215546Sopenharmony_ci 547bf215546Sopenharmony_cistatic uint32_t 548bf215546Sopenharmony_cimsm_ringbuffer_emit_reloc_ring(struct fd_ringbuffer *ring, 549bf215546Sopenharmony_ci struct fd_ringbuffer *target, uint32_t cmd_idx) 550bf215546Sopenharmony_ci{ 551bf215546Sopenharmony_ci struct msm_ringbuffer *msm_target = to_msm_ringbuffer(target); 552bf215546Sopenharmony_ci struct msm_ringbuffer *msm_ring = to_msm_ringbuffer(ring); 553bf215546Sopenharmony_ci struct fd_bo *bo; 554bf215546Sopenharmony_ci uint32_t size; 555bf215546Sopenharmony_ci 556bf215546Sopenharmony_ci if ((target->flags & FD_RINGBUFFER_GROWABLE) && 557bf215546Sopenharmony_ci (cmd_idx < msm_target->u.nr_cmds)) { 558bf215546Sopenharmony_ci bo = msm_target->u.cmds[cmd_idx]->ring_bo; 559bf215546Sopenharmony_ci size = msm_target->u.cmds[cmd_idx]->size; 560bf215546Sopenharmony_ci } else { 561bf215546Sopenharmony_ci bo = msm_target->ring_bo; 562bf215546Sopenharmony_ci size = offset_bytes(target->cur, target->start); 563bf215546Sopenharmony_ci } 564bf215546Sopenharmony_ci 565bf215546Sopenharmony_ci msm_ringbuffer_emit_reloc(ring, &(struct fd_reloc){ 566bf215546Sopenharmony_ci .bo = bo, 567bf215546Sopenharmony_ci .iova = bo->iova + msm_target->offset, 568bf215546Sopenharmony_ci .offset = msm_target->offset, 569bf215546Sopenharmony_ci }); 570bf215546Sopenharmony_ci 571bf215546Sopenharmony_ci if (!size) 572bf215546Sopenharmony_ci return 0; 573bf215546Sopenharmony_ci 574bf215546Sopenharmony_ci if ((target->flags & _FD_RINGBUFFER_OBJECT) && 575bf215546Sopenharmony_ci !(ring->flags & _FD_RINGBUFFER_OBJECT)) { 576bf215546Sopenharmony_ci struct msm_submit *msm_submit = to_msm_submit(msm_ring->u.submit); 577bf215546Sopenharmony_ci 578bf215546Sopenharmony_ci append_stateobj_rings(msm_submit, target); 579bf215546Sopenharmony_ci } 580bf215546Sopenharmony_ci 581bf215546Sopenharmony_ci if (ring->flags & _FD_RINGBUFFER_OBJECT) { 582bf215546Sopenharmony_ci append_ring(msm_ring->u.ring_set, target); 583bf215546Sopenharmony_ci } else { 584bf215546Sopenharmony_ci struct msm_submit *msm_submit = to_msm_submit(msm_ring->u.submit); 585bf215546Sopenharmony_ci append_ring(msm_submit->ring_set, target); 586bf215546Sopenharmony_ci } 587bf215546Sopenharmony_ci 588bf215546Sopenharmony_ci return size; 589bf215546Sopenharmony_ci} 590bf215546Sopenharmony_ci 591bf215546Sopenharmony_cistatic uint32_t 592bf215546Sopenharmony_cimsm_ringbuffer_cmd_count(struct fd_ringbuffer *ring) 593bf215546Sopenharmony_ci{ 594bf215546Sopenharmony_ci if (ring->flags & FD_RINGBUFFER_GROWABLE) 595bf215546Sopenharmony_ci return to_msm_ringbuffer(ring)->u.nr_cmds + 1; 596bf215546Sopenharmony_ci return 1; 597bf215546Sopenharmony_ci} 598bf215546Sopenharmony_ci 599bf215546Sopenharmony_cistatic bool 600bf215546Sopenharmony_cimsm_ringbuffer_check_size(struct fd_ringbuffer *ring) 601bf215546Sopenharmony_ci{ 602bf215546Sopenharmony_ci assert(!(ring->flags & _FD_RINGBUFFER_OBJECT)); 603bf215546Sopenharmony_ci struct msm_ringbuffer *msm_ring = to_msm_ringbuffer(ring); 604bf215546Sopenharmony_ci struct fd_submit *submit = msm_ring->u.submit; 605bf215546Sopenharmony_ci struct fd_pipe *pipe = submit->pipe; 606bf215546Sopenharmony_ci 607bf215546Sopenharmony_ci if ((fd_device_version(pipe->dev) < FD_VERSION_UNLIMITED_CMDS) && 608bf215546Sopenharmony_ci ((ring->cur - ring->start) > (ring->size / 4 - 0x1000))) { 609bf215546Sopenharmony_ci return false; 610bf215546Sopenharmony_ci } 611bf215546Sopenharmony_ci 612bf215546Sopenharmony_ci if (to_msm_submit(submit)->nr_bos > MAX_ARRAY_SIZE/2) { 613bf215546Sopenharmony_ci return false; 614bf215546Sopenharmony_ci } 615bf215546Sopenharmony_ci 616bf215546Sopenharmony_ci return true; 617bf215546Sopenharmony_ci} 618bf215546Sopenharmony_ci 619bf215546Sopenharmony_cistatic void 620bf215546Sopenharmony_cimsm_ringbuffer_destroy(struct fd_ringbuffer *ring) 621bf215546Sopenharmony_ci{ 622bf215546Sopenharmony_ci struct msm_ringbuffer *msm_ring = to_msm_ringbuffer(ring); 623bf215546Sopenharmony_ci 624bf215546Sopenharmony_ci fd_bo_del(msm_ring->ring_bo); 625bf215546Sopenharmony_ci if (msm_ring->cmd) 626bf215546Sopenharmony_ci cmd_free(msm_ring->cmd); 627bf215546Sopenharmony_ci 628bf215546Sopenharmony_ci if (ring->flags & _FD_RINGBUFFER_OBJECT) { 629bf215546Sopenharmony_ci for (unsigned i = 0; i < msm_ring->u.nr_reloc_bos; i++) { 630bf215546Sopenharmony_ci fd_bo_del(msm_ring->u.reloc_bos[i]); 631bf215546Sopenharmony_ci } 632bf215546Sopenharmony_ci 633bf215546Sopenharmony_ci _mesa_set_destroy(msm_ring->u.ring_set, unref_rings); 634bf215546Sopenharmony_ci 635bf215546Sopenharmony_ci free(msm_ring->u.reloc_bos); 636bf215546Sopenharmony_ci free(msm_ring); 637bf215546Sopenharmony_ci } else { 638bf215546Sopenharmony_ci struct fd_submit *submit = msm_ring->u.submit; 639bf215546Sopenharmony_ci 640bf215546Sopenharmony_ci for (unsigned i = 0; i < msm_ring->u.nr_cmds; i++) { 641bf215546Sopenharmony_ci cmd_free(msm_ring->u.cmds[i]); 642bf215546Sopenharmony_ci } 643bf215546Sopenharmony_ci 644bf215546Sopenharmony_ci free(msm_ring->u.cmds); 645bf215546Sopenharmony_ci slab_free_st(&to_msm_submit(submit)->ring_pool, msm_ring); 646bf215546Sopenharmony_ci } 647bf215546Sopenharmony_ci} 648bf215546Sopenharmony_ci 649bf215546Sopenharmony_cistatic const struct fd_ringbuffer_funcs ring_funcs = { 650bf215546Sopenharmony_ci .grow = msm_ringbuffer_grow, 651bf215546Sopenharmony_ci .emit_reloc = msm_ringbuffer_emit_reloc, 652bf215546Sopenharmony_ci .emit_reloc_ring = msm_ringbuffer_emit_reloc_ring, 653bf215546Sopenharmony_ci .cmd_count = msm_ringbuffer_cmd_count, 654bf215546Sopenharmony_ci .check_size = msm_ringbuffer_check_size, 655bf215546Sopenharmony_ci .destroy = msm_ringbuffer_destroy, 656bf215546Sopenharmony_ci}; 657bf215546Sopenharmony_ci 658bf215546Sopenharmony_cistatic inline struct fd_ringbuffer * 659bf215546Sopenharmony_cimsm_ringbuffer_init(struct msm_ringbuffer *msm_ring, uint32_t size, 660bf215546Sopenharmony_ci enum fd_ringbuffer_flags flags) 661bf215546Sopenharmony_ci{ 662bf215546Sopenharmony_ci struct fd_ringbuffer *ring = &msm_ring->base; 663bf215546Sopenharmony_ci 664bf215546Sopenharmony_ci assert(msm_ring->ring_bo); 665bf215546Sopenharmony_ci 666bf215546Sopenharmony_ci uint8_t *base = fd_bo_map(msm_ring->ring_bo); 667bf215546Sopenharmony_ci ring->start = (void *)(base + msm_ring->offset); 668bf215546Sopenharmony_ci ring->end = &(ring->start[size / 4]); 669bf215546Sopenharmony_ci ring->cur = ring->start; 670bf215546Sopenharmony_ci 671bf215546Sopenharmony_ci ring->size = size; 672bf215546Sopenharmony_ci ring->flags = flags; 673bf215546Sopenharmony_ci 674bf215546Sopenharmony_ci ring->funcs = &ring_funcs; 675bf215546Sopenharmony_ci 676bf215546Sopenharmony_ci msm_ring->u.cmds = NULL; 677bf215546Sopenharmony_ci msm_ring->u.nr_cmds = msm_ring->u.max_cmds = 0; 678bf215546Sopenharmony_ci 679bf215546Sopenharmony_ci msm_ring->cmd = cmd_new(msm_ring->ring_bo); 680bf215546Sopenharmony_ci 681bf215546Sopenharmony_ci return ring; 682bf215546Sopenharmony_ci} 683bf215546Sopenharmony_ci 684bf215546Sopenharmony_cistruct fd_ringbuffer * 685bf215546Sopenharmony_cimsm_ringbuffer_new_object(struct fd_pipe *pipe, uint32_t size) 686bf215546Sopenharmony_ci{ 687bf215546Sopenharmony_ci struct msm_ringbuffer *msm_ring = malloc(sizeof(*msm_ring)); 688bf215546Sopenharmony_ci 689bf215546Sopenharmony_ci msm_ring->u.pipe = pipe; 690bf215546Sopenharmony_ci msm_ring->offset = 0; 691bf215546Sopenharmony_ci msm_ring->ring_bo = fd_bo_new_ring(pipe->dev, size); 692bf215546Sopenharmony_ci msm_ring->base.refcnt = 1; 693bf215546Sopenharmony_ci 694bf215546Sopenharmony_ci msm_ring->u.reloc_bos = NULL; 695bf215546Sopenharmony_ci msm_ring->u.nr_reloc_bos = msm_ring->u.max_reloc_bos = 0; 696bf215546Sopenharmony_ci 697bf215546Sopenharmony_ci msm_ring->u.ring_set = 698bf215546Sopenharmony_ci _mesa_set_create(NULL, _mesa_hash_pointer, _mesa_key_pointer_equal); 699bf215546Sopenharmony_ci 700bf215546Sopenharmony_ci return msm_ringbuffer_init(msm_ring, size, _FD_RINGBUFFER_OBJECT); 701bf215546Sopenharmony_ci} 702