virtualization.lists.linux-foundation.org archive mirror
 help / color / mirror / Atom feed
* Re: [PATCH 2/2] virtio-serial: setup_port_vq when adding port
       [not found] ` <1326331207-10339-3-git-send-email-zanghongyong@huawei.com>
@ 2012-02-01  8:12   ` Amit Shah
  2012-02-01  9:32     ` Zang Hongyong
  0 siblings, 1 reply; 3+ messages in thread
From: Amit Shah @ 2012-02-01  8:12 UTC (permalink / raw)
  To: zanghongyong
  Cc: aliguori, kvm, wusongwei, hanweidong, Virtualization List,
	xiaowei.yang, jiangningyu

Hi,

Sorry for the late reply.

On (Thu) 12 Jan 2012 [09:20:07], zanghongyong@huawei.com wrote:
> From: Hongyong Zang <zanghongyong@huawei.com>
> 
> Add setup_port_vq(). Create the io ports' vqs when add_port.

Can you describe the changes in more detail, please?

> Signed-off-by: Hongyong Zang <zanghongyong@huawei.com>
> ---
>  drivers/char/virtio_console.c |   65 ++++++++++++++++++++++++++++++++++++++--
>  1 files changed, 61 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c
> index 8e3c46d..2e5187e 100644
> --- a/drivers/char/virtio_console.c
> +++ b/drivers/char/virtio_console.c
> @@ -1132,6 +1132,55 @@ static void send_sigio_to_port(struct port *port)
>  		kill_fasync(&port->async_queue, SIGIO, POLL_OUT);
>  }
>  
> +static void in_intr(struct virtqueue *vq);
> +static void out_intr(struct virtqueue *vq);
> +
> +static int setup_port_vq(struct ports_device *portdev,  u32 id)
> +{
> +	int err, vq_num;
> +	vq_callback_t **io_callbacks;
> +	char **io_names;
> +	struct virtqueue **vqs;
> +	u32 i,j,nr_ports,nr_queues;
> +
> +	err = 0;
> +	vq_num = (id + 1) * 2;
> +	nr_ports = portdev->config.max_nr_ports;
> +	nr_queues = use_multiport(portdev) ? (nr_ports + 1) * 2 : 2;
> +
> +	vqs = kmalloc(nr_queues * sizeof(struct virtqueue *), GFP_KERNEL);
> +	io_callbacks = kmalloc(nr_queues * sizeof(vq_callback_t *), GFP_KERNEL);
> +	io_names = kmalloc(nr_queues * sizeof(char *), GFP_KERNEL);
> +	if (!vqs || !io_callbacks || !io_names) {
> +		err = -ENOMEM;
> +		goto free;
> +	}
> +
> +	for (i = 0, j = 0; i <= nr_ports; i++) {
> +		io_callbacks[j] = in_intr;
> +		io_callbacks[j + 1] = out_intr;
> +		io_names[j] = NULL;
> +		io_names[j + 1] = NULL;
> +		j += 2;
> +	}
> +	io_names[vq_num] = "serial-input";
> +	io_names[vq_num + 1] = "serial-output";
> +	err = portdev->vdev->config->find_vqs(portdev->vdev, nr_queues, vqs,
> +				io_callbacks,
> +				(const char **)io_names);
> +	if (err)
> +		goto free;
> +	portdev->in_vqs[id] = vqs[vq_num];
> +	portdev->out_vqs[id] = vqs[vq_num + 1];

I don't think this approach will work fine for port hot-plug /
hot-unplug cases at all.  For example, I first start qemu with one
port, at id 1.  Then I add a port at id 5, then at 2, then at 10.
Will that be fine?

> +
> +free:
> +	kfree(io_names);
> +	kfree(io_callbacks);
> +	kfree(vqs);
> +
> +	return err;
> +}
> +
>  static int add_port(struct ports_device *portdev, u32 id)
>  {
>  	char debugfs_name[16];
> @@ -1163,6 +1212,14 @@ static int add_port(struct ports_device *portdev, u32 id)
>  
>  	port->outvq_full = false;
>  
> +	if (!portdev->in_vqs[port->id] && !portdev->out_vqs[port->id]) {
> +		spin_lock(&portdev->ports_lock);
> +		err = setup_port_vq(portdev, port->id);
> +		spin_unlock(&portdev->ports_lock);
> +		if (err)
> +			goto free_port;
> +	}
> +
>  	port->in_vq = portdev->in_vqs[port->id];
>  	port->out_vq = portdev->out_vqs[port->id];
>  
> @@ -1614,8 +1671,8 @@ static int init_vqs(struct ports_device *portdev)
>  			j += 2;
>  			io_callbacks[j] = in_intr;
>  			io_callbacks[j + 1] = out_intr;
> -			io_names[j] = "input";
> -			io_names[j + 1] = "output";
> +			io_names[j] = NULL;
> +			io_names[j + 1] = NULL;
>  		}
>  	}
>  	/* Find the queues. */
> @@ -1635,8 +1692,8 @@ static int init_vqs(struct ports_device *portdev)
>  
>  		for (i = 1; i < nr_ports; i++) {
>  			j += 2;
> -			portdev->in_vqs[i] = vqs[j];
> -			portdev->out_vqs[i] = vqs[j + 1];
> +			portdev->in_vqs[i] = NULL;
> +			portdev->out_vqs[i] = NULL;
>  		}
>  	}
>  	kfree(io_names);

So a queue once created will not be removed unless the module is
removed or the device is removed.  That seems reasonable, port
hot-unplug will keep queues around, as is the case now.

		Amit

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH 1/2] virtio-pci: add setup_vqs flag in vp_try_to_find_vqs
       [not found] ` <1326331207-10339-2-git-send-email-zanghongyong@huawei.com>
@ 2012-02-01  8:14   ` Amit Shah
  0 siblings, 0 replies; 3+ messages in thread
From: Amit Shah @ 2012-02-01  8:14 UTC (permalink / raw)
  To: zanghongyong
  Cc: aliguori, kvm, wusongwei, hanweidong, Virtualization List,
	xiaowei.yang, Michael S. Tsirkin, jiangningyu

Michael, Rusty, any comments?

On (Thu) 12 Jan 2012 [09:20:06], zanghongyong@huawei.com wrote:
> From: Hongyong Zang <zanghongyong@huawei.com>
> 
> changes in vp_try_to_find_vqs:
> Virtio-serial's probe() calls it to request irqs and setup vqs of port0 and
> controls; add_port() calls it to set up vqs of io_port.
> it will not create virtqueue if the name is null.
> 
> Signed-off-by: Hongyong Zang <zanghongyong@huawei.com>
> ---
>  drivers/virtio/virtio_pci.c |   17 +++++++++++++----
>  1 files changed, 13 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/virtio/virtio_pci.c b/drivers/virtio/virtio_pci.c
> index baabb79..1f98c36 100644
> --- a/drivers/virtio/virtio_pci.c
> +++ b/drivers/virtio/virtio_pci.c
> @@ -492,9 +492,11 @@ static void vp_del_vqs(struct virtio_device *vdev)
>  	list_for_each_entry_safe(vq, n, &vdev->vqs, list) {
>  		info = vq->priv;
>  		if (vp_dev->per_vq_vectors &&
> -			info->msix_vector != VIRTIO_MSI_NO_VECTOR)
> +			info->msix_vector != VIRTIO_MSI_NO_VECTOR) {
>  			free_irq(vp_dev->msix_entries[info->msix_vector].vector,
>  				 vq);
> +			vp_dev->msix_used_vectors--;
> +		}
>  		vp_del_vq(vq);
>  	}
>  	vp_dev->per_vq_vectors = false;
> @@ -511,7 +513,10 @@ static int vp_try_to_find_vqs(struct virtio_device *vdev, unsigned nvqs,
>  {
>  	struct virtio_pci_device *vp_dev = to_vp_device(vdev);
>  	u16 msix_vec;
> -	int i, err, nvectors, allocated_vectors;
> +	int i, err, nvectors;
> +
> +	if (vp_dev->msix_used_vectors)
> +		goto setup_vqs;
>  
>  	if (!use_msix) {
>  		/* Old style: one normal interrupt for change and all vqs. */
> @@ -536,12 +541,16 @@ static int vp_try_to_find_vqs(struct virtio_device *vdev, unsigned nvqs,
>  	}
>  
>  	vp_dev->per_vq_vectors = per_vq_vectors;
> -	allocated_vectors = vp_dev->msix_used_vectors;
> +
> +setup_vqs:
>  	for (i = 0; i < nvqs; ++i) {
> +		if (names[i] == NULL)
> +			continue;
> +
>  		if (!callbacks[i] || !vp_dev->msix_enabled)
>  			msix_vec = VIRTIO_MSI_NO_VECTOR;
>  		else if (vp_dev->per_vq_vectors)
> -			msix_vec = allocated_vectors++;
> +			msix_vec = vp_dev->msix_used_vectors++;
>  		else
>  			msix_vec = VP_MSIX_VQ_VECTOR;
>  		vqs[i] = setup_vq(vdev, i, callbacks[i], names[i], msix_vec);
> -- 
> 1.7.1
> 

		Amit

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH 2/2] virtio-serial: setup_port_vq when adding port
  2012-02-01  8:12   ` [PATCH 2/2] virtio-serial: setup_port_vq when adding port Amit Shah
@ 2012-02-01  9:32     ` Zang Hongyong
  0 siblings, 0 replies; 3+ messages in thread
From: Zang Hongyong @ 2012-02-01  9:32 UTC (permalink / raw)
  To: Amit Shah
  Cc: aliguori, kvm, wusongwei, hanweidong, Virtualization List,
	xiaowei.yang, jiangningyu

On 2012/2/1,星期三 16:12, Amit Shah wrote:
> Hi,
>
> Sorry for the late reply.
>
> On (Thu) 12 Jan 2012 [09:20:07], zanghongyong@huawei.com wrote:
>> From: Hongyong Zang<zanghongyong@huawei.com>
>>
>> Add setup_port_vq(). Create the io ports' vqs when add_port.
> Can you describe the changes in more detail, please?

The motivation of this patch is as follows. When we use virtio-serial
for communication between guest and host, we usually use only a few
ports (for example 1 or 2 ports), so there's no need to create max ports
when build a virtio-serial. The patch does the port hot-plug thing without
port hot-unplug.
>
>> Signed-off-by: Hongyong Zang<zanghongyong@huawei.com>
>> ---
>>   drivers/char/virtio_console.c |   65 ++++++++++++++++++++++++++++++++++++++--
>>   1 files changed, 61 insertions(+), 4 deletions(-)
>>
>> diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c
>> index 8e3c46d..2e5187e 100644
>> --- a/drivers/char/virtio_console.c
>> +++ b/drivers/char/virtio_console.c
>> @@ -1132,6 +1132,55 @@ static void send_sigio_to_port(struct port *port)
>>   		kill_fasync(&port->async_queue, SIGIO, POLL_OUT);
>>   }
>>
>> +static void in_intr(struct virtqueue *vq);
>> +static void out_intr(struct virtqueue *vq);
>> +
>> +static int setup_port_vq(struct ports_device *portdev,  u32 id)
>> +{
>> +	int err, vq_num;
>> +	vq_callback_t **io_callbacks;
>> +	char **io_names;
>> +	struct virtqueue **vqs;
>> +	u32 i,j,nr_ports,nr_queues;
>> +
>> +	err = 0;
>> +	vq_num = (id + 1) * 2;
>> +	nr_ports = portdev->config.max_nr_ports;
>> +	nr_queues = use_multiport(portdev) ? (nr_ports + 1) * 2 : 2;
>> +
>> +	vqs = kmalloc(nr_queues * sizeof(struct virtqueue *), GFP_KERNEL);
>> +	io_callbacks = kmalloc(nr_queues * sizeof(vq_callback_t *), GFP_KERNEL);
>> +	io_names = kmalloc(nr_queues * sizeof(char *), GFP_KERNEL);
>> +	if (!vqs || !io_callbacks || !io_names) {
>> +		err = -ENOMEM;
>> +		goto free;
>> +	}
>> +
>> +	for (i = 0, j = 0; i<= nr_ports; i++) {
>> +		io_callbacks[j] = in_intr;
>> +		io_callbacks[j + 1] = out_intr;
>> +		io_names[j] = NULL;
>> +		io_names[j + 1] = NULL;
>> +		j += 2;
>> +	}
>> +	io_names[vq_num] = "serial-input";
>> +	io_names[vq_num + 1] = "serial-output";
>> +	err = portdev->vdev->config->find_vqs(portdev->vdev, nr_queues, vqs,
>> +				io_callbacks,
>> +				(const char **)io_names);
>> +	if (err)
>> +		goto free;
>> +	portdev->in_vqs[id] = vqs[vq_num];
>> +	portdev->out_vqs[id] = vqs[vq_num + 1];
> I don't think this approach will work fine for port hot-plug /
> hot-unplug cases at all.  For example, I first start qemu with one
> port, at id 1.  Then I add a port at id 5, then at 2, then at 10.
> Will that be fine?

yes.
In this case, the virtio-serial will create id 1's queue when probe the
device. Then, add port id 5, it will create the id 5's queue and the queues
of id 2-4 still be null.
we find the right ioport by vq_num, and only the io_name[vq_num] and
io_name[vq_num+1] are not null. So after portdev->vdev->config->find_vqs(),
the id 5's queues are created(see the changes in virtio-pci), the others 
are
still null.
>
>> +
>> +free:
>> +	kfree(io_names);
>> +	kfree(io_callbacks);
>> +	kfree(vqs);
>> +
>> +	return err;
>> +}
>> +
>>   static int add_port(struct ports_device *portdev, u32 id)
>>   {
>>   	char debugfs_name[16];
>> @@ -1163,6 +1212,14 @@ static int add_port(struct ports_device *portdev, u32 id)
>>
>>   	port->outvq_full = false;
>>
>> +	if (!portdev->in_vqs[port->id]&&  !portdev->out_vqs[port->id]) {
>> +		spin_lock(&portdev->ports_lock);
>> +		err = setup_port_vq(portdev, port->id);
>> +		spin_unlock(&portdev->ports_lock);
>> +		if (err)
>> +			goto free_port;
>> +	}
>> +
>>   	port->in_vq = portdev->in_vqs[port->id];
>>   	port->out_vq = portdev->out_vqs[port->id];
>>
>> @@ -1614,8 +1671,8 @@ static int init_vqs(struct ports_device *portdev)
>>   			j += 2;
>>   			io_callbacks[j] = in_intr;
>>   			io_callbacks[j + 1] = out_intr;
>> -			io_names[j] = "input";
>> -			io_names[j + 1] = "output";
>> +			io_names[j] = NULL;
>> +			io_names[j + 1] = NULL;
>>   		}
>>   	}
>>   	/* Find the queues. */
>> @@ -1635,8 +1692,8 @@ static int init_vqs(struct ports_device *portdev)
>>
>>   		for (i = 1; i<  nr_ports; i++) {
>>   			j += 2;
>> -			portdev->in_vqs[i] = vqs[j];
>> -			portdev->out_vqs[i] = vqs[j + 1];
>> +			portdev->in_vqs[i] = NULL;
>> +			portdev->out_vqs[i] = NULL;
>>   		}
>>   	}
>>   	kfree(io_names);
> So a queue once created will not be removed unless the module is
> removed or the device is removed.  That seems reasonable, port
> hot-unplug will keep queues around, as is the case now.

As we use the virtio-serial with only a few io-ports, the maxport queues 
may
waste more memory. So we try to create queues when port hot-plug, as for
port hot-unplug there's no change.

>
> 		Amit
>
> .
>


_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2012-02-01  9:32 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <1326331207-10339-1-git-send-email-zanghongyong@huawei.com>
     [not found] ` <1326331207-10339-3-git-send-email-zanghongyong@huawei.com>
2012-02-01  8:12   ` [PATCH 2/2] virtio-serial: setup_port_vq when adding port Amit Shah
2012-02-01  9:32     ` Zang Hongyong
     [not found] ` <1326331207-10339-2-git-send-email-zanghongyong@huawei.com>
2012-02-01  8:14   ` [PATCH 1/2] virtio-pci: add setup_vqs flag in vp_try_to_find_vqs Amit Shah

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).