unsigned int num_elem)
 {
        enum queue_type type = q->type;
+       u32 new_prod;
        u32 prod;
        u32 cons;
 
        if (!queue_empty(q, q->type) && (num_elem < queue_count(q, type)))
                return -EINVAL;
 
-       prod = queue_get_producer(new_q, type);
+       new_prod = queue_get_producer(new_q, type);
+       prod = queue_get_producer(q, type);
        cons = queue_get_consumer(q, type);
 
-       while (!queue_empty(q, type)) {
-               memcpy(queue_addr_from_index(new_q, prod),
+       while ((prod - cons) & q->index_mask) {
+               memcpy(queue_addr_from_index(new_q, new_prod),
                       queue_addr_from_index(q, cons), new_q->elem_size);
-               prod = queue_next_index(new_q, prod);
+               new_prod = queue_next_index(new_q, new_prod);
                cons = queue_next_index(q, cons);
        }
 
-       new_q->buf->producer_index = prod;
+       new_q->buf->producer_index = new_prod;
        q->buf->consumer_index = cons;
 
        /* update private index copies */