static void setup_desc_rgn(struct sbd_link_device *sl) { unsigned int size; #if 0 mif_err("SHMEM {base:0x%08X size:%d}\n", (int)sl->shmem, sl->shmem_size); #endif /* Allocate @g_desc. */ size = sizeof(struct sbd_global_desc); sl->g_desc = (struct sbd_global_desc *)desc_alloc(sl, size); #if 0 mif_err("G_DESC_OFFSET = %d(0x%08X)\n", calc_offset(sl->g_desc, sl->shmem), (int)sl->g_desc); mif_err("RB_CH_OFFSET = %d (0x%08X)\n", calc_offset(sl->g_desc->rb_ch, sl->shmem), (int)sl->g_desc->rb_ch); mif_err("RBD_PAIR_OFFSET = %d (0x%08X)\n", calc_offset(sl->g_desc->rb_desc, sl->shmem), (int)sl->g_desc->rb_desc); #endif size = sizeof(u16) * ULDL * RDWR * sl->num_channels; sl->rbps = (u16 *)desc_alloc(sl, size); #if 0 mif_err("RBP_SET_OFFSET = %d (0x%08X)\n", calc_offset(sl->rbps, sl->shmem), (int)sl->rbps); #endif /* Set up @g_desc. */ sl->g_desc->version = sl->version; sl->g_desc->num_channels = sl->num_channels; sl->g_desc->rbps_offset = calc_offset(sl->rbps, sl->shmem); /* Set up pointers to each RBP array. */ sl->rp[UL] = sl->rbps + sl->num_channels * 0; sl->wp[UL] = sl->rbps + sl->num_channels * 1; sl->rp[DL] = sl->rbps + sl->num_channels * 2; sl->wp[DL] = sl->rbps + sl->num_channels * 3; }
static gpointer alloc_from_new_sb (MonoLockFreeAllocator *heap) { unsigned int slot_size, block_size, count, i; Descriptor *desc = desc_alloc (heap->account_type); slot_size = desc->slot_size = heap->sc->slot_size; block_size = desc->block_size = heap->sc->block_size; count = LOCK_FREE_ALLOC_SB_USABLE_SIZE (block_size) / slot_size; desc->heap = heap; /* * Setting avail to 1 because 0 is the block we're allocating * right away. */ desc->anchor.data.avail = 1; desc->slot_size = heap->sc->slot_size; desc->max_count = count; desc->anchor.data.count = desc->max_count - 1; desc->anchor.data.state = STATE_PARTIAL; desc->sb = alloc_sb (desc); /* Organize blocks into linked list. */ for (i = 1; i < count - 1; ++i) *(unsigned int*)((char*)desc->sb + i * slot_size) = i + 1; *(unsigned int*)((char*)desc->sb + (count - 1) * slot_size) = 0; mono_memory_write_barrier (); /* Make it active or free it again. */ if (mono_atomic_cas_ptr ((volatile gpointer *)&heap->active, desc, NULL) == NULL) { return desc->sb; } else { desc->anchor.data.state = STATE_EMPTY; desc_retire (desc); return NULL; } }
static gpointer alloc_from_new_sb (MonoLockFreeAllocator *heap) { unsigned int slot_size, count, i; Descriptor *desc = desc_alloc (); desc->sb = alloc_sb (desc); slot_size = desc->slot_size = heap->sc->slot_size; count = SB_USABLE_SIZE / slot_size; /* Organize blocks into linked list. */ for (i = 1; i < count - 1; ++i) *(unsigned int*)((char*)desc->sb + i * slot_size) = i + 1; desc->heap = heap; /* * Setting avail to 1 because 0 is the block we're allocating * right away. */ desc->anchor.data.avail = 1; desc->slot_size = heap->sc->slot_size; desc->max_count = count; desc->anchor.data.count = desc->max_count - 1; desc->anchor.data.state = STATE_PARTIAL; mono_memory_write_barrier (); /* Make it active or free it again. */ if (InterlockedCompareExchangePointer ((gpointer * volatile)&heap->active, desc, NULL) == NULL) { return desc->sb; } else { desc->anchor.data.state = STATE_EMPTY; desc_retire (desc); return NULL; } }
/** @brief set up an SBD RB (1) build an SBD RB instance in the kernel space\n (2) allocate an SBD array in SHMEM\n (3) allocate a data buffer array in SHMEM if possible\n */ static int setup_sbd_rb(struct sbd_link_device *sl, struct sbd_ring_buffer *rb, enum direction dir, struct sbd_link_attr *link_attr) { unsigned int alloc_size; int i; rb->sl = sl; rb->lnk_hdr = link_attr->lnk_hdr; rb->more = false; rb->total = 0; rb->rcvd = 0; /* Initialize an SBD RB instance in the kernel space. */ rb->id = link_attr->id; rb->ch = link_attr->ch; rb->dir = dir; rb->len = link_attr->rb_len[dir]; rb->buff_size = link_attr->buff_size[dir]; rb->payload_offset = 0; /* Prepare array of pointers to the data buffer for each SBD */ alloc_size = (rb->len * sizeof(u8 *)); rb->buff = kmalloc(alloc_size, GFP_ATOMIC); if (!rb->buff) return -ENOMEM; /* (1) Allocate an array of data buffers in SHMEM. (2) Register the address of each data buffer. */ alloc_size = (rb->len * rb->buff_size); rb->buff_rgn = (u8 *)buff_alloc(sl, alloc_size); if (!rb->buff_rgn) return -ENOMEM; for (i = 0; i < rb->len; i++) rb->buff[i] = rb->buff_rgn + (i * rb->buff_size); #if 0 mif_err("RB[%d:%d][%s] buff_rgn {addr:0x%08X offset:%d size:%d}\n", rb->id, rb->ch, udl_str(dir), (int)rb->buff_rgn, calc_offset(rb->buff_rgn, sl->shmem), alloc_size); #endif /* Prepare SBD array in SHMEM. */ rb->rp = &sl->rp[rb->dir][rb->id]; rb->wp = &sl->wp[rb->dir][rb->id]; alloc_size = (rb->len * sizeof(u32)); rb->addr_v = (u32 *)desc_alloc(sl, alloc_size); if (!rb->addr_v) return -ENOMEM; rb->size_v = (u32 *)desc_alloc(sl, alloc_size); if (!rb->size_v) return -ENOMEM; /* Register each data buffer to the corresponding SBD. */ for (i = 0; i < rb->len; i++) { rb->addr_v[i] = calc_offset(rb->buff[i], sl->shmem); rb->size_v[i] = 0; } rb->iod = link_get_iod_with_channel(sl->ld, rb->ch); rb->ld = sl->ld; return 0; }