[RFC PATCH 1/2] rpmsg: virtio_rpmsg_bus: allow the different vring size for send/recv

Tanmay Shah posted 2 patches 2 months, 3 weeks ago
[RFC PATCH 1/2] rpmsg: virtio_rpmsg_bus: allow the different vring size for send/recv
Posted by Tanmay Shah 2 months, 3 weeks ago
From: Xiang Xiao <xiaoxiang781216@gmail.com>

it's useful if the communication throughput is different from each side

Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
Signed-off-by: Tanmay Shah <tanmay.shah@amd.com>
---
 drivers/rpmsg/virtio_rpmsg_bus.c | 47 ++++++++++++++++----------------
 1 file changed, 24 insertions(+), 23 deletions(-)

diff --git a/drivers/rpmsg/virtio_rpmsg_bus.c b/drivers/rpmsg/virtio_rpmsg_bus.c
index 484890b4a6a7..cc26dfcc3e29 100644
--- a/drivers/rpmsg/virtio_rpmsg_bus.c
+++ b/drivers/rpmsg/virtio_rpmsg_bus.c
@@ -37,8 +37,9 @@
  * @svq:	tx virtqueue
  * @rbufs:	kernel address of rx buffers
  * @sbufs:	kernel address of tx buffers
- * @num_bufs:	total number of buffers for rx and tx
- * @buf_size:   size of one rx or tx buffer
+ * @num_rbufs:	total number of buffers for rx
+ * @num_sbufs:	total number of buffers for tx
+ * @buf_size:	size of one rx or tx buffer
  * @last_sbuf:	index of last tx buffer used
  * @bufs_dma:	dma base addr of the buffers
  * @tx_lock:	protects svq, sbufs and sleepers, to allow concurrent senders.
@@ -57,7 +58,8 @@ struct virtproc_info {
 	struct virtio_device *vdev;
 	struct virtqueue *rvq, *svq;
 	void *rbufs, *sbufs;
-	unsigned int num_bufs;
+	unsigned int num_rbufs;
+	unsigned int num_sbufs;
 	unsigned int buf_size;
 	int last_sbuf;
 	dma_addr_t bufs_dma;
@@ -112,7 +114,7 @@ struct virtio_rpmsg_channel {
 /*
  * We're allocating buffers of 512 bytes each for communications. The
  * number of buffers will be computed from the number of buffers supported
- * by the vring, upto a maximum of 512 buffers (256 in each direction).
+ * by the vring, up to a maximum of 256 in each direction.
  *
  * Each buffer will have 16 bytes for the msg header and 496 bytes for
  * the payload.
@@ -127,7 +129,7 @@ struct virtio_rpmsg_channel {
  * can change this without changing anything in the firmware of the remote
  * processor.
  */
-#define MAX_RPMSG_NUM_BUFS	(512)
+#define MAX_RPMSG_NUM_BUFS	(256)
 #define MAX_RPMSG_BUF_SIZE	(512)
 
 /*
@@ -439,11 +441,8 @@ static void *get_a_tx_buf(struct virtproc_info *vrp)
 	/* support multiple concurrent senders */
 	mutex_lock(&vrp->tx_lock);
 
-	/*
-	 * either pick the next unused tx buffer
-	 * (half of our buffers are used for sending messages)
-	 */
-	if (vrp->last_sbuf < vrp->num_bufs / 2)
+	/* either pick the next unused tx buffer */
+	if (vrp->last_sbuf < vrp->num_sbufs)
 		ret = vrp->sbufs + vrp->buf_size * vrp->last_sbuf++;
 	/* or recycle a used one */
 	else
@@ -878,19 +877,20 @@ static int rpmsg_probe(struct virtio_device *vdev)
 	vrp->rvq = vqs[0];
 	vrp->svq = vqs[1];
 
-	/* we expect symmetric tx/rx vrings */
-	WARN_ON(virtqueue_get_vring_size(vrp->rvq) !=
-		virtqueue_get_vring_size(vrp->svq));
-
 	/* we need less buffers if vrings are small */
-	if (virtqueue_get_vring_size(vrp->rvq) < MAX_RPMSG_NUM_BUFS / 2)
-		vrp->num_bufs = virtqueue_get_vring_size(vrp->rvq) * 2;
+	if (virtqueue_get_vring_size(vrp->rvq) < MAX_RPMSG_NUM_BUFS)
+		vrp->num_rbufs = virtqueue_get_vring_size(vrp->rvq);
+	else
+		vrp->num_rbufs = MAX_RPMSG_NUM_BUFS;
+
+	if (virtqueue_get_vring_size(vrp->svq) < MAX_RPMSG_NUM_BUFS)
+		vrp->num_sbufs = virtqueue_get_vring_size(vrp->svq);
 	else
-		vrp->num_bufs = MAX_RPMSG_NUM_BUFS;
+		vrp->num_sbufs = MAX_RPMSG_NUM_BUFS;
 
 	vrp->buf_size = MAX_RPMSG_BUF_SIZE;
 
-	total_buf_space = vrp->num_bufs * vrp->buf_size;
+	total_buf_space = (vrp->num_rbufs + vrp->num_sbufs) * vrp->buf_size;
 
 	/* allocate coherent memory for the buffers */
 	bufs_va = dma_alloc_coherent(vdev->dev.parent,
@@ -904,14 +904,14 @@ static int rpmsg_probe(struct virtio_device *vdev)
 	dev_dbg(&vdev->dev, "buffers: va %p, dma %pad\n",
 		bufs_va, &vrp->bufs_dma);
 
-	/* half of the buffers is dedicated for RX */
+	/* first part of the buffers is dedicated for RX */
 	vrp->rbufs = bufs_va;
 
-	/* and half is dedicated for TX */
-	vrp->sbufs = bufs_va + total_buf_space / 2;
+	/* and second part is dedicated for TX */
+	vrp->sbufs = bufs_va + vrp->num_rbufs * vrp->buf_size;
 
 	/* set up the receive buffers */
-	for (i = 0; i < vrp->num_bufs / 2; i++) {
+	for (i = 0; i < vrp->num_rbufs; i++) {
 		struct scatterlist sg;
 		void *cpu_addr = vrp->rbufs + i * vrp->buf_size;
 
@@ -1001,7 +1001,8 @@ static int rpmsg_remove_device(struct device *dev, void *data)
 static void rpmsg_remove(struct virtio_device *vdev)
 {
 	struct virtproc_info *vrp = vdev->priv;
-	size_t total_buf_space = vrp->num_bufs * vrp->buf_size;
+	unsigned int num_bufs = vrp->num_rbufs + vrp->num_sbufs;
+	size_t total_buf_space = num_bufs * vrp->buf_size;
 	int ret;
 
 	virtio_reset_device(vdev);
-- 
2.34.1
Re: [RFC PATCH 1/2] rpmsg: virtio_rpmsg_bus: allow the different vring size for send/recv
Posted by Mathieu Poirier 1 month, 3 weeks ago
Hi Tanmay,

On Fri, Nov 14, 2025 at 10:46:39AM -0800, Tanmay Shah wrote:
> From: Xiang Xiao <xiaoxiang781216@gmail.com>
>

This feature has been abandoned a long time ago - you own it now.
 
> it's useful if the communication throughput is different from each side
> 

Please provide a better changelog.

> Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
> Signed-off-by: Tanmay Shah <tanmay.shah@amd.com>
> ---
>  drivers/rpmsg/virtio_rpmsg_bus.c | 47 ++++++++++++++++----------------
>  1 file changed, 24 insertions(+), 23 deletions(-)
> 
> diff --git a/drivers/rpmsg/virtio_rpmsg_bus.c b/drivers/rpmsg/virtio_rpmsg_bus.c
> index 484890b4a6a7..cc26dfcc3e29 100644
> --- a/drivers/rpmsg/virtio_rpmsg_bus.c
> +++ b/drivers/rpmsg/virtio_rpmsg_bus.c
> @@ -37,8 +37,9 @@
>   * @svq:	tx virtqueue
>   * @rbufs:	kernel address of rx buffers
>   * @sbufs:	kernel address of tx buffers
> - * @num_bufs:	total number of buffers for rx and tx
> - * @buf_size:   size of one rx or tx buffer
> + * @num_rbufs:	total number of buffers for rx
> + * @num_sbufs:	total number of buffers for tx
> + * @buf_size:	size of one rx or tx buffer
>   * @last_sbuf:	index of last tx buffer used
>   * @bufs_dma:	dma base addr of the buffers
>   * @tx_lock:	protects svq, sbufs and sleepers, to allow concurrent senders.
> @@ -57,7 +58,8 @@ struct virtproc_info {
>  	struct virtio_device *vdev;
>  	struct virtqueue *rvq, *svq;
>  	void *rbufs, *sbufs;
> -	unsigned int num_bufs;
> +	unsigned int num_rbufs;
> +	unsigned int num_sbufs;
>  	unsigned int buf_size;
>  	int last_sbuf;
>  	dma_addr_t bufs_dma;
> @@ -112,7 +114,7 @@ struct virtio_rpmsg_channel {
>  /*
>   * We're allocating buffers of 512 bytes each for communications. The
>   * number of buffers will be computed from the number of buffers supported
> - * by the vring, upto a maximum of 512 buffers (256 in each direction).
> + * by the vring, up to a maximum of 256 in each direction.
>   *
>   * Each buffer will have 16 bytes for the msg header and 496 bytes for
>   * the payload.
> @@ -127,7 +129,7 @@ struct virtio_rpmsg_channel {
>   * can change this without changing anything in the firmware of the remote
>   * processor.
>   */
> -#define MAX_RPMSG_NUM_BUFS	(512)
> +#define MAX_RPMSG_NUM_BUFS	(256)
>  #define MAX_RPMSG_BUF_SIZE	(512)
>  
>  /*
> @@ -439,11 +441,8 @@ static void *get_a_tx_buf(struct virtproc_info *vrp)
>  	/* support multiple concurrent senders */
>  	mutex_lock(&vrp->tx_lock);
>  
> -	/*
> -	 * either pick the next unused tx buffer
> -	 * (half of our buffers are used for sending messages)
> -	 */
> -	if (vrp->last_sbuf < vrp->num_bufs / 2)
> +	/* either pick the next unused tx buffer */
> +	if (vrp->last_sbuf < vrp->num_sbufs)
>  		ret = vrp->sbufs + vrp->buf_size * vrp->last_sbuf++;
>  	/* or recycle a used one */
>  	else
> @@ -878,19 +877,20 @@ static int rpmsg_probe(struct virtio_device *vdev)
>  	vrp->rvq = vqs[0];
>  	vrp->svq = vqs[1];
>  
> -	/* we expect symmetric tx/rx vrings */
> -	WARN_ON(virtqueue_get_vring_size(vrp->rvq) !=
> -		virtqueue_get_vring_size(vrp->svq));
> -
>  	/* we need less buffers if vrings are small */
> -	if (virtqueue_get_vring_size(vrp->rvq) < MAX_RPMSG_NUM_BUFS / 2)
> -		vrp->num_bufs = virtqueue_get_vring_size(vrp->rvq) * 2;
> +	if (virtqueue_get_vring_size(vrp->rvq) < MAX_RPMSG_NUM_BUFS)
> +		vrp->num_rbufs = virtqueue_get_vring_size(vrp->rvq);
> +	else
> +		vrp->num_rbufs = MAX_RPMSG_NUM_BUFS;
> +
> +	if (virtqueue_get_vring_size(vrp->svq) < MAX_RPMSG_NUM_BUFS)
> +		vrp->num_sbufs = virtqueue_get_vring_size(vrp->svq);
>  	else
> -		vrp->num_bufs = MAX_RPMSG_NUM_BUFS;
> +		vrp->num_sbufs = MAX_RPMSG_NUM_BUFS;
>  
>  	vrp->buf_size = MAX_RPMSG_BUF_SIZE;
>  
> -	total_buf_space = vrp->num_bufs * vrp->buf_size;
> +	total_buf_space = (vrp->num_rbufs + vrp->num_sbufs) * vrp->buf_size;
>  
>  	/* allocate coherent memory for the buffers */
>  	bufs_va = dma_alloc_coherent(vdev->dev.parent,
> @@ -904,14 +904,14 @@ static int rpmsg_probe(struct virtio_device *vdev)
>  	dev_dbg(&vdev->dev, "buffers: va %p, dma %pad\n",
>  		bufs_va, &vrp->bufs_dma);
>  
> -	/* half of the buffers is dedicated for RX */
> +	/* first part of the buffers is dedicated for RX */
>  	vrp->rbufs = bufs_va;
>  
> -	/* and half is dedicated for TX */
> -	vrp->sbufs = bufs_va + total_buf_space / 2;
> +	/* and second part is dedicated for TX */
> +	vrp->sbufs = bufs_va + vrp->num_rbufs * vrp->buf_size;
>  
>  	/* set up the receive buffers */
> -	for (i = 0; i < vrp->num_bufs / 2; i++) {
> +	for (i = 0; i < vrp->num_rbufs; i++) {
>  		struct scatterlist sg;
>  		void *cpu_addr = vrp->rbufs + i * vrp->buf_size;
>  
> @@ -1001,7 +1001,8 @@ static int rpmsg_remove_device(struct device *dev, void *data)
>  static void rpmsg_remove(struct virtio_device *vdev)
>  {
>  	struct virtproc_info *vrp = vdev->priv;
> -	size_t total_buf_space = vrp->num_bufs * vrp->buf_size;
> +	unsigned int num_bufs = vrp->num_rbufs + vrp->num_sbufs;
> +	size_t total_buf_space = num_bufs * vrp->buf_size;
>  	int ret;
>  
>  	virtio_reset_device(vdev);
> -- 
> 2.34.1
>
Re: [RFC PATCH 1/2] rpmsg: virtio_rpmsg_bus: allow the different vring size for send/recv
Posted by Arnaud POULIQUEN 2 months, 2 weeks ago
Hi Tanmay,

On 11/14/25 19:46, Tanmay Shah wrote:
> From: Xiang Xiao <xiaoxiang781216@gmail.com>
> 
> it's useful if the communication throughput is different from each side
> 
> Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
> Signed-off-by: Tanmay Shah <tanmay.shah@amd.com>


Thanks you for reopening of this series!
> ---
>   drivers/rpmsg/virtio_rpmsg_bus.c | 47 ++++++++++++++++----------------
>   1 file changed, 24 insertions(+), 23 deletions(-)
> 
> diff --git a/drivers/rpmsg/virtio_rpmsg_bus.c b/drivers/rpmsg/virtio_rpmsg_bus.c
> index 484890b4a6a7..cc26dfcc3e29 100644
> --- a/drivers/rpmsg/virtio_rpmsg_bus.c
> +++ b/drivers/rpmsg/virtio_rpmsg_bus.c
> @@ -37,8 +37,9 @@
>    * @svq:	tx virtqueue
>    * @rbufs:	kernel address of rx buffers
>    * @sbufs:	kernel address of tx buffers
> - * @num_bufs:	total number of buffers for rx and tx
> - * @buf_size:   size of one rx or tx buffer
> + * @num_rbufs:	total number of buffers for rx
> + * @num_sbufs:	total number of buffers for tx

Nitpicking... I wonder if rx, tx term would be more generic
In such case s/num_rxbufs/n_rx_buf/ s/num_sbufs/num_txbufs/

Regards
Arnaud

> + * @buf_size:	size of one rx or tx buffer
>    * @last_sbuf:	index of last tx buffer used
>    * @bufs_dma:	dma base addr of the buffers
>    * @tx_lock:	protects svq, sbufs and sleepers, to allow concurrent senders.
> @@ -57,7 +58,8 @@ struct virtproc_info {
>   	struct virtio_device *vdev;
>   	struct virtqueue *rvq, *svq;
>   	void *rbufs, *sbufs;
> -	unsigned int num_bufs;
> +	unsigned int num_rbufs;
> +	unsigned int num_sbufs;
>   	unsigned int buf_size;
>   	int last_sbuf;
>   	dma_addr_t bufs_dma;
> @@ -112,7 +114,7 @@ struct virtio_rpmsg_channel {
>   /*
>    * We're allocating buffers of 512 bytes each for communications. The
>    * number of buffers will be computed from the number of buffers supported
> - * by the vring, upto a maximum of 512 buffers (256 in each direction).
> + * by the vring, up to a maximum of 256 in each direction.
>    *
>    * Each buffer will have 16 bytes for the msg header and 496 bytes for
>    * the payload.
> @@ -127,7 +129,7 @@ struct virtio_rpmsg_channel {
>    * can change this without changing anything in the firmware of the remote
>    * processor.
>    */
> -#define MAX_RPMSG_NUM_BUFS	(512)
> +#define MAX_RPMSG_NUM_BUFS	(256)
>   #define MAX_RPMSG_BUF_SIZE	(512)
>   
>   /*
> @@ -439,11 +441,8 @@ static void *get_a_tx_buf(struct virtproc_info *vrp)
>   	/* support multiple concurrent senders */
>   	mutex_lock(&vrp->tx_lock);
>   
> -	/*
> -	 * either pick the next unused tx buffer
> -	 * (half of our buffers are used for sending messages)
> -	 */
> -	if (vrp->last_sbuf < vrp->num_bufs / 2)
> +	/* either pick the next unused tx buffer */
> +	if (vrp->last_sbuf < vrp->num_sbufs)
>   		ret = vrp->sbufs + vrp->buf_size * vrp->last_sbuf++;
>   	/* or recycle a used one */
>   	else
> @@ -878,19 +877,20 @@ static int rpmsg_probe(struct virtio_device *vdev)
>   	vrp->rvq = vqs[0];
>   	vrp->svq = vqs[1];
>   
> -	/* we expect symmetric tx/rx vrings */
> -	WARN_ON(virtqueue_get_vring_size(vrp->rvq) !=
> -		virtqueue_get_vring_size(vrp->svq));
> -
>   	/* we need less buffers if vrings are small */
> -	if (virtqueue_get_vring_size(vrp->rvq) < MAX_RPMSG_NUM_BUFS / 2)
> -		vrp->num_bufs = virtqueue_get_vring_size(vrp->rvq) * 2;
> +	if (virtqueue_get_vring_size(vrp->rvq) < MAX_RPMSG_NUM_BUFS)
> +		vrp->num_rbufs = virtqueue_get_vring_size(vrp->rvq);
> +	else
> +		vrp->num_rbufs = MAX_RPMSG_NUM_BUFS;
> +
> +	if (virtqueue_get_vring_size(vrp->svq) < MAX_RPMSG_NUM_BUFS)
> +		vrp->num_sbufs = virtqueue_get_vring_size(vrp->svq);
>   	else
> -		vrp->num_bufs = MAX_RPMSG_NUM_BUFS;
> +		vrp->num_sbufs = MAX_RPMSG_NUM_BUFS;
>   
>   	vrp->buf_size = MAX_RPMSG_BUF_SIZE;
>   
> -	total_buf_space = vrp->num_bufs * vrp->buf_size;
> +	total_buf_space = (vrp->num_rbufs + vrp->num_sbufs) * vrp->buf_size;
>   
>   	/* allocate coherent memory for the buffers */
>   	bufs_va = dma_alloc_coherent(vdev->dev.parent,
> @@ -904,14 +904,14 @@ static int rpmsg_probe(struct virtio_device *vdev)
>   	dev_dbg(&vdev->dev, "buffers: va %p, dma %pad\n",
>   		bufs_va, &vrp->bufs_dma);
>   
> -	/* half of the buffers is dedicated for RX */
> +	/* first part of the buffers is dedicated for RX */
>   	vrp->rbufs = bufs_va;
>   
> -	/* and half is dedicated for TX */
> -	vrp->sbufs = bufs_va + total_buf_space / 2;
> +	/* and second part is dedicated for TX */
> +	vrp->sbufs = bufs_va + vrp->num_rbufs * vrp->buf_size;
>   
>   	/* set up the receive buffers */
> -	for (i = 0; i < vrp->num_bufs / 2; i++) {
> +	for (i = 0; i < vrp->num_rbufs; i++) {
>   		struct scatterlist sg;
>   		void *cpu_addr = vrp->rbufs + i * vrp->buf_size;
>   
> @@ -1001,7 +1001,8 @@ static int rpmsg_remove_device(struct device *dev, void *data)
>   static void rpmsg_remove(struct virtio_device *vdev)
>   {
>   	struct virtproc_info *vrp = vdev->priv;
> -	size_t total_buf_space = vrp->num_bufs * vrp->buf_size;
> +	unsigned int num_bufs = vrp->num_rbufs + vrp->num_sbufs;
> +	size_t total_buf_space = num_bufs * vrp->buf_size;
>   	int ret;
>   
>   	virtio_reset_device(vdev);
Re: [RFC PATCH 1/2] rpmsg: virtio_rpmsg_bus: allow the different vring size for send/recv
Posted by Tanmay Shah 2 months, 1 week ago

On 11/21/25 3:40 AM, Arnaud POULIQUEN wrote:
> Hi Tanmay,
> 
> On 11/14/25 19:46, Tanmay Shah wrote:
>> From: Xiang Xiao <xiaoxiang781216@gmail.com>
>>
>> it's useful if the communication throughput is different from each side
>>
>> Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
>> Signed-off-by: Tanmay Shah <tanmay.shah@amd.com>
> 
> 
> Thanks you for reopening of this series!
>> ---
>>   drivers/rpmsg/virtio_rpmsg_bus.c | 47 ++++++++++++++++----------------
>>   1 file changed, 24 insertions(+), 23 deletions(-)
>>
>> diff --git a/drivers/rpmsg/virtio_rpmsg_bus.c b/drivers/rpmsg/ 
>> virtio_rpmsg_bus.c
>> index 484890b4a6a7..cc26dfcc3e29 100644
>> --- a/drivers/rpmsg/virtio_rpmsg_bus.c
>> +++ b/drivers/rpmsg/virtio_rpmsg_bus.c
>> @@ -37,8 +37,9 @@
>>    * @svq:    tx virtqueue
>>    * @rbufs:    kernel address of rx buffers
>>    * @sbufs:    kernel address of tx buffers
>> - * @num_bufs:    total number of buffers for rx and tx
>> - * @buf_size:   size of one rx or tx buffer
>> + * @num_rbufs:    total number of buffers for rx
>> + * @num_sbufs:    total number of buffers for tx
> 
> Nitpicking... I wonder if rx, tx term would be more generic
> In such case s/num_rxbufs/n_rx_buf/ s/num_sbufs/num_txbufs/
> 

Ack. I can change that.

> Regards
> Arnaud
> 
>> + * @buf_size:    size of one rx or tx buffer
>>    * @last_sbuf:    index of last tx buffer used
>>    * @bufs_dma:    dma base addr of the buffers
>>    * @tx_lock:    protects svq, sbufs and sleepers, to allow 
>> concurrent senders.
>> @@ -57,7 +58,8 @@ struct virtproc_info {
>>       struct virtio_device *vdev;
>>       struct virtqueue *rvq, *svq;
>>       void *rbufs, *sbufs;
>> -    unsigned int num_bufs;
>> +    unsigned int num_rbufs;
>> +    unsigned int num_sbufs;
>>       unsigned int buf_size;
>>       int last_sbuf;
>>       dma_addr_t bufs_dma;
>> @@ -112,7 +114,7 @@ struct virtio_rpmsg_channel {
>>   /*
>>    * We're allocating buffers of 512 bytes each for communications. The
>>    * number of buffers will be computed from the number of buffers 
>> supported
>> - * by the vring, upto a maximum of 512 buffers (256 in each direction).
>> + * by the vring, up to a maximum of 256 in each direction.
>>    *
>>    * Each buffer will have 16 bytes for the msg header and 496 bytes for
>>    * the payload.
>> @@ -127,7 +129,7 @@ struct virtio_rpmsg_channel {
>>    * can change this without changing anything in the firmware of the 
>> remote
>>    * processor.
>>    */
>> -#define MAX_RPMSG_NUM_BUFS    (512)
>> +#define MAX_RPMSG_NUM_BUFS    (256)
>>   #define MAX_RPMSG_BUF_SIZE    (512)
>>   /*
>> @@ -439,11 +441,8 @@ static void *get_a_tx_buf(struct virtproc_info *vrp)
>>       /* support multiple concurrent senders */
>>       mutex_lock(&vrp->tx_lock);
>> -    /*
>> -     * either pick the next unused tx buffer
>> -     * (half of our buffers are used for sending messages)
>> -     */
>> -    if (vrp->last_sbuf < vrp->num_bufs / 2)
>> +    /* either pick the next unused tx buffer */
>> +    if (vrp->last_sbuf < vrp->num_sbufs)
>>           ret = vrp->sbufs + vrp->buf_size * vrp->last_sbuf++;
>>       /* or recycle a used one */
>>       else
>> @@ -878,19 +877,20 @@ static int rpmsg_probe(struct virtio_device *vdev)
>>       vrp->rvq = vqs[0];
>>       vrp->svq = vqs[1];
>> -    /* we expect symmetric tx/rx vrings */
>> -    WARN_ON(virtqueue_get_vring_size(vrp->rvq) !=
>> -        virtqueue_get_vring_size(vrp->svq));
>> -
>>       /* we need less buffers if vrings are small */
>> -    if (virtqueue_get_vring_size(vrp->rvq) < MAX_RPMSG_NUM_BUFS / 2)
>> -        vrp->num_bufs = virtqueue_get_vring_size(vrp->rvq) * 2;
>> +    if (virtqueue_get_vring_size(vrp->rvq) < MAX_RPMSG_NUM_BUFS)
>> +        vrp->num_rbufs = virtqueue_get_vring_size(vrp->rvq);
>> +    else
>> +        vrp->num_rbufs = MAX_RPMSG_NUM_BUFS;
>> +
>> +    if (virtqueue_get_vring_size(vrp->svq) < MAX_RPMSG_NUM_BUFS)
>> +        vrp->num_sbufs = virtqueue_get_vring_size(vrp->svq);
>>       else
>> -        vrp->num_bufs = MAX_RPMSG_NUM_BUFS;
>> +        vrp->num_sbufs = MAX_RPMSG_NUM_BUFS;
>>       vrp->buf_size = MAX_RPMSG_BUF_SIZE;
>> -    total_buf_space = vrp->num_bufs * vrp->buf_size;
>> +    total_buf_space = (vrp->num_rbufs + vrp->num_sbufs) * vrp->buf_size;
>>       /* allocate coherent memory for the buffers */
>>       bufs_va = dma_alloc_coherent(vdev->dev.parent,
>> @@ -904,14 +904,14 @@ static int rpmsg_probe(struct virtio_device *vdev)
>>       dev_dbg(&vdev->dev, "buffers: va %p, dma %pad\n",
>>           bufs_va, &vrp->bufs_dma);
>> -    /* half of the buffers is dedicated for RX */
>> +    /* first part of the buffers is dedicated for RX */
>>       vrp->rbufs = bufs_va;
>> -    /* and half is dedicated for TX */
>> -    vrp->sbufs = bufs_va + total_buf_space / 2;
>> +    /* and second part is dedicated for TX */
>> +    vrp->sbufs = bufs_va + vrp->num_rbufs * vrp->buf_size;
>>       /* set up the receive buffers */
>> -    for (i = 0; i < vrp->num_bufs / 2; i++) {
>> +    for (i = 0; i < vrp->num_rbufs; i++) {
>>           struct scatterlist sg;
>>           void *cpu_addr = vrp->rbufs + i * vrp->buf_size;
>> @@ -1001,7 +1001,8 @@ static int rpmsg_remove_device(struct device 
>> *dev, void *data)
>>   static void rpmsg_remove(struct virtio_device *vdev)
>>   {
>>       struct virtproc_info *vrp = vdev->priv;
>> -    size_t total_buf_space = vrp->num_bufs * vrp->buf_size;
>> +    unsigned int num_bufs = vrp->num_rbufs + vrp->num_sbufs;
>> +    size_t total_buf_space = num_bufs * vrp->buf_size;
>>       int ret;
>>       virtio_reset_device(vdev);
>