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;
}
Ejemplo n.º 2
0
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;
	}
}
Ejemplo n.º 3
0
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;
}