+ mq->alloc_bufs++;
+ ns--;
+ count--;
+ }
+
+no_ns:
+
+ DBG ("allocated: %u/%u bufs. Total %u allocated bufs", *count_out, count,
+ mq->alloc_bufs);
+
+ if (count)
+ {
+ DBG ("ring buffer full! qid: %u", qid);
+ err = MEMIF_ERR_NOBUF_RING;
+ }
+
+ return err;
+}
+
+int
+memif_refill_queue (memif_conn_handle_t conn, uint16_t qid, uint16_t count,
+ uint16_t headroom)
+{
+ memif_connection_t *c = (memif_connection_t *) conn;
+ if (EXPECT_FALSE (c == NULL))
+ return MEMIF_ERR_NOCONN;
+ if (EXPECT_FALSE (c->fd < 0))
+ return MEMIF_ERR_DISCONNECTED;
+ uint8_t num =
+ (c->args.is_master) ? c->run_args.num_s2m_rings : c->
+ run_args.num_m2s_rings;
+ if (EXPECT_FALSE (qid >= num))
+ return MEMIF_ERR_QID;
+ libmemif_main_t *lm = &libmemif_main;
+ memif_queue_t *mq = &c->rx_queues[qid];
+ memif_ring_t *ring = mq->ring;
+ uint16_t mask = (1 << mq->log2_ring_size) - 1;
+ uint32_t offset_mask = c->run_args.buffer_size - 1;
+ uint16_t slot;
+
+ if (c->args.is_master)
+ {
+ MEMIF_MEMORY_BARRIER ();
+ ring->tail =
+ (ring->tail + count <=
+ mq->last_head) ? ring->tail + count : mq->last_head;
+ return MEMIF_ERR_SUCCESS;
+ }
+
+ uint16_t head = ring->head;
+ uint16_t ns = (1 << mq->log2_ring_size) - head + mq->last_tail;
+ head += (count < ns) ? count : ns;
+
+ slot = ring->head;
+ memif_desc_t *d;
+ while (slot < head)
+ {
+ d = &ring->desc[slot & mask];
+ d->region = 1;
+ d->length = c->run_args.buffer_size - headroom;
+ if (lm->get_external_buffer_offset)
+ d->offset = lm->get_external_buffer_offset (c->private_ctx);
+ else
+ d->offset = d->offset - (d->offset & offset_mask) + headroom;
+ slot++;