Linux virtualization list
 help / color / mirror / Atom feed
* ACM MTAGS 2011: deadline extension to September 26th
From: Ioan Raicu @ 2011-09-05 17:41 UTC (permalink / raw)
  To: virtualization


[-- Attachment #1.1: Type: text/plain, Size: 2226 bytes --]

CALL FOR PAPERS
4th Workshop on Many-Task Computing on Grids and Supercomputers (MTAGS) 2011

http://datasys.cs.iit.edu/events/MTAGS11/index.html
http://sc11.supercomputing.org/schedule/event_detail.php?evid=wksp122

***DEADLINE EXTENSION -- September 26th, 2011*

The 4th workshop on Many-Task Computing on Grids and Supercomputers 
(MTAGS11) will provide the scientific community a dedicated forum for 
presenting new research, development, and deployment efforts of 
large-scale many-task computing (MTC) applications on large scale 
clusters, Grids, Supercomputers, and Cloud Computing infrastructure. 
MTC, the theme of the workshop encompasses loosely coupled applications, 
which are generally composed of many tasks (both independent and 
dependent tasks) to achieve some larger application goal. This workshop 
will cover challenges that can hamper efficiency and utilization in 
running applications on large-scale systems, such as local resource 
manager scalability and granularity, efficient utilization of raw 
hardware, parallel file system contention and scalability, data 
management, I/O management, reliability at scale, and application 
scalability.

*General Chairs (mtags11-chairs@datasys.cs.iit.edu 
<mailto:mtags11-chairs@datasys.cs.iit.edu>)*

  * Ioan Raicu, Illinois Institute of Technology & Argonne National
    Laboratory, USA
  * Ian Foster, University of Chicago & Argonne National Laboratory, USA
  * Yong Zhao, University of Electronic Science and Technology of China,
    China

-- 
=================================================================
Ioan Raicu, Ph.D.
Assistant Professor, Illinois Institute of Technology (IIT)
Guest Research Faculty, Argonne National Laboratory (ANL)
=================================================================
Data-Intensive Distributed Systems Laboratory, CS/IIT
Distributed Systems Laboratory, MCS/ANL
=================================================================
Cel:    1-847-722-0876
Office: 1-312-567-5704
Email:  iraicu@cs.iit.edu
Web:    http://www.cs.iit.edu/~iraicu/
Web:    http://datasys.cs.iit.edu/
=================================================================
=================================================================



[-- Attachment #1.2: Type: text/html, Size: 3319 bytes --]

[-- Attachment #2: Type: text/plain, Size: 184 bytes --]

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

^ permalink raw reply

* ACM DataCloud-SC11 2011: deadline extension to September 26th
From: Ioan Raicu @ 2011-09-05 17:49 UTC (permalink / raw)
  To: virtualization


[-- Attachment #1.1: Type: text/plain, Size: 2040 bytes --]

CALL FOR PAPERS
The Second International Workshop on Data-Intensive Computing in the 
Clouds (DataCloud-SC11) 2011

http://datasys.cs.iit.edu/events/DataCloud-SC11/index.html
http://sc11.supercomputing.org/schedule/event_detail.php?evid=wksp119

***DEADLINE EXTENSION -- September 26th, 2011*

The second international workshop on Data-intensive Computing in the 
Clouds (DataCloud-SC11) will provide the scientific community a 
dedicated forum for discussing new research, development, and deployment 
efforts in running data-intensive computing workloads on Cloud Computing 
infrastructures. The DataCloud-SC11 workshop will focus on the use of 
cloud-based technologies to meet the new data intensive scientific 
challenges that are not well served by the current supercomputers, grids 
or compute-intensive clouds. We believe the workshop will be an 
excellent place to help the community define the current state, 
determine future goals, and present architectures and services for 
future clouds supporting data intensive computing.

*General Chairs (datacloud-sc11-chairs@datasys.cs.iit.edu 
<mailto:datacloud-sc11-chairs@datasys.cs.iit.edu>)*

  * Ioan Raicu, Illinois Institute of Technology & Argonne National
    Laboratory, USA
  * Tevfik Kosar,  University at Buffalo, USA
  * Roger Barga, Microsoft Research, USA

-- 
=================================================================
Ioan Raicu, Ph.D.
Assistant Professor, Illinois Institute of Technology (IIT)
Guest Research Faculty, Argonne National Laboratory (ANL)
=================================================================
Data-Intensive Distributed Systems Laboratory, CS/IIT
Distributed Systems Laboratory, MCS/ANL
=================================================================
Cel:    1-847-722-0876
Office: 1-312-567-5704
Email:  iraicu@cs.iit.edu
Web:    http://www.cs.iit.edu/~iraicu/
Web:    http://datasys.cs.iit.edu/
=================================================================
=================================================================



[-- Attachment #1.2: Type: text/html, Size: 3127 bytes --]

[-- Attachment #2: Type: text/plain, Size: 184 bytes --]

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

^ permalink raw reply

* RE: [PATCH 1/1] staging: hv: Add support for >2 TB LUN in storage driver.
From: Mike Sterling @ 2011-09-06 15:33 UTC (permalink / raw)
  To: Greg KH
  Cc: Haiyang Zhang, Hank Janssen, KY Srinivasan,
	linux-kernel@vger.kernel.org, devel@linuxdriverproject.org,
	virtualization@lists.osdl.org
In-Reply-To: <20110901222206.GA18024@suse.de>

On Thu, Sep 1, 2011 at 03:22:00PM +0800, Greg KH wrote:
>On Thu, Sep 01, 2011 at 03:11:09PM -0700, Mike Sterling wrote:
>> If a LUN larger than 2 TB is attached to a Linux VM on Hyper-V, we 
>> currently report a maximum size of 2 TB. This patch resolves the issue in hv_storvsc.
>> Thanks to Robert Scheck <robert.scheck@etes.de> for reporting the issue.
>> 
>> Reported-by: Robert Scheck <robert.scheck@etes.de>
>> Signed-off-by: Mike Sterling <mike.sterling@microsoft.com>
>> Signed-off-by: K.Y. Srinivasan <kys@microsoft.com>
>> Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
>
>Much better, thanks.
>
>Is this something that needs to go to older kernels (3.0, 2.6.32, etc.) as well?

I discussed this with Ky. Given the changes that have taken place with the hv_* code, it's unlikely that this patch would just work with downlevel kernels. I'll need to create separate patches for those kernels.

-Mike

^ permalink raw reply

* Re: [PATCH 1/1] staging: hv: Add support for >2 TB LUN in storage driver.
From: Greg KH @ 2011-09-06 19:06 UTC (permalink / raw)
  To: Mike Sterling
  Cc: haiyangz, hjanssen, kys, gregkh, linux-kernel, devel,
	virtualization
In-Reply-To: <1314915069-1796-1-git-send-email-mike.sterling@microsoft.com>

On Thu, Sep 01, 2011 at 03:11:09PM -0700, Mike Sterling wrote:
> If a LUN larger than 2 TB is attached to a Linux VM on Hyper-V, we currently 
> report a maximum size of 2 TB. This patch resolves the issue in hv_storvsc. 
> Thanks to Robert Scheck <robert.scheck@etes.de> for reporting the issue.
> 
> Reported-by: Robert Scheck <robert.scheck@etes.de>
> Signed-off-by: Mike Sterling <mike.sterling@microsoft.com>
> Signed-off-by: K.Y. Srinivasan <kys@microsoft.com>
> Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
> ---
>  drivers/staging/hv/hyperv_storage.h |    1 +

This file is no longer in the latest kernel tree (linux-next or
staging-next).  What tree did you generate this patch against?  And
how come Haiyang and KY didn't catch such a basic mistake in their
review...

I'm guessing that this patch was not even tested :(

Please fix this and resend.

greg k-h

^ permalink raw reply

* RE: [PATCH 1/1] staging: hv: Add support for >2 TB LUN in storage driver.
From: Mike Sterling @ 2011-09-06 19:14 UTC (permalink / raw)
  To: Greg KH
  Cc: Haiyang Zhang, gregkh@suse.de, linux-kernel@vger.kernel.org,
	virtualization@lists.osdl.org, devel@linuxdriverproject.org
In-Reply-To: <20110906190615.GA31897@kroah.com>

On Tuesday, September 06, 2011 12:06 PM, Greg KH wrote:
>On Thu, Sep 01, 2011 at 03:11:09PM -0700, Mike Sterling wrote:
>> If a LUN larger than 2 TB is attached to a Linux VM on Hyper-V, we 
>> currently report a maximum size of 2 TB. This patch resolves the issue in hv_storvsc.
>> Thanks to Robert Scheck <robert.scheck@etes.de> for reporting the issue.
>> 
>> Reported-by: Robert Scheck <robert.scheck@etes.de>
>> Signed-off-by: Mike Sterling <mike.sterling@microsoft.com>
>> Signed-off-by: K.Y. Srinivasan <kys@microsoft.com>
>> Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
>> ---
>>  drivers/staging/hv/hyperv_storage.h |    1 +
>
>This file is no longer in the latest kernel tree (linux-next or staging-next).  What tree did you generate this patch against?  And >how come Haiyang and KY didn't catch such a basic mistake in their review...
>
>I'm guessing that this patch was not even tested :(
>
>Please fix this and resend.

Greg,

This patch was reviewed by both Ky and Haiyang. However, it looks like I built the patch against an older tree that didn't have Ky's changes. The "how" is still unclear, even after reviewing my steps with Ky. I've discussed this with Ky, I'm rebuilding the patch today, and will resubmit once we confirm.

-Mike

^ permalink raw reply

* [PATCH 1/1] Staging: hv: Add support for >2 TB LUN in storage driver.
From: Mike Sterling @ 2011-09-06 23:10 UTC (permalink / raw)
  To: haiyangz, hjanssen, kys, gregkh, linux-kernel, devel,
	virtualization
  Cc: Mike Sterling

From: Mike Sterling <mike.sterling@microsoft.com> 

If a LUN larger than 2 TB is attached to a Linux VM on Hyper-V, we currently
report a maximum size of 2 TB. This patch resolves the issue in hv_storvsc.
Thanks to Robert Scheck <robert.scheck@etes.de> for reporting the issue.

Reported-by: Robert Scheck <robert.scheck@etes.de>
Signed-off-by: Mike Sterling <mike.sterling@microsoft.com>
Signed-off-by: K.Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 drivers/staging/hv/storvsc_drv.c |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c
index 3686d10..b0c4e56 100644
--- a/drivers/staging/hv/storvsc_drv.c
+++ b/drivers/staging/hv/storvsc_drv.c
@@ -232,6 +232,7 @@ struct vstor_packet {
 #define STORVSC_MAX_LUNS_PER_TARGET			64
 #define STORVSC_MAX_TARGETS				1
 #define STORVSC_MAX_CHANNELS				1
+#define STORVSC_MAX_CMD_LEN				16
 
 struct hv_storvsc_request;
 
@@ -1440,6 +1441,8 @@ static int storvsc_probe(struct hv_device *device)
 	host->max_id = STORVSC_MAX_TARGETS;
 	/* max # of channels */
 	host->max_channel = STORVSC_MAX_CHANNELS - 1;
+	/* max cmd length */
+	host->max_cmd_len = STORVSC_MAX_CMD_LEN;
 
 	/* Register the HBA and start the scsi bus scan */
 	ret = scsi_add_host(host, &device->device);
-- 
1.7.4.1

^ permalink raw reply related

* Re: [PATCH 2/2] tools/virtio: virtio_test tool
From: Zhi Yong Wu @ 2011-09-07  3:34 UTC (permalink / raw)
  To: Michael S. Tsirkin; +Cc: linux-kernel, kvm, virtualization
In-Reply-To: <20101129171637.GC4027@redhat.com>

Thanks. very good learning material.

On Tue, Nov 30, 2010 at 1:16 AM, Michael S. Tsirkin <mst@redhat.com> wrote:
> This is the userspace part of the tool: it includes a bunch of stubs for
> linux APIs, somewhat simular to linuxsched. This makes it possible to
> recompile the ring code in userspace.
>
> A small test example is implemented combining this with vhost_test
> module.
>
> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
>
> ---
>
> diff --git a/tools/virtio/Makefile b/tools/virtio/Makefile
> new file mode 100644
> index 0000000..d1d442e
> --- /dev/null
> +++ b/tools/virtio/Makefile
> @@ -0,0 +1,12 @@
> +all: test mod
> +test: virtio_test
> +virtio_test: virtio_ring.o virtio_test.o
> +CFLAGS += -g -O2 -Wall -I. -I ../../usr/include/ -Wno-pointer-sign -fno-strict-overflow  -MMD
> +vpath %.c ../../drivers/virtio
> +mod:
> +       ${MAKE} -C `pwd`/../.. M=`pwd`/vhost_test
> +.PHONY: all test mod clean
> +clean:
> +       ${RM} *.o vhost_test/*.o vhost_test/.*.cmd \
> +              vhost_test/Module.symvers vhost_test/modules.order *.d
> +-include *.d
> diff --git a/tools/virtio/linux/device.h b/tools/virtio/linux/device.h
> new file mode 100644
> index 0000000..4ad7e1d
> --- /dev/null
> +++ b/tools/virtio/linux/device.h
> @@ -0,0 +1,2 @@
> +#ifndef LINUX_DEVICE_H
> +#endif
> diff --git a/tools/virtio/linux/slab.h b/tools/virtio/linux/slab.h
> new file mode 100644
> index 0000000..81baeac
> --- /dev/null
> +++ b/tools/virtio/linux/slab.h
> @@ -0,0 +1,2 @@
> +#ifndef LINUX_SLAB_H
> +#endif
> diff --git a/tools/virtio/linux/virtio.h b/tools/virtio/linux/virtio.h
> new file mode 100644
> index 0000000..669bcdd
> --- /dev/null
> +++ b/tools/virtio/linux/virtio.h
> @@ -0,0 +1,223 @@
> +#ifndef LINUX_VIRTIO_H
> +#define LINUX_VIRTIO_H
> +
> +#include <stdbool.h>
> +#include <stdlib.h>
> +#include <stddef.h>
> +#include <stdio.h>
> +#include <string.h>
> +#include <assert.h>
> +
> +#include <linux/types.h>
> +#include <errno.h>
> +
> +typedef unsigned long long dma_addr_t;
> +
> +struct scatterlist {
> +       unsigned long   page_link;
> +       unsigned int    offset;
> +       unsigned int    length;
> +       dma_addr_t      dma_address;
> +};
> +
> +struct page {
> +       unsigned long long dummy;
> +};
> +
> +#define BUG_ON(__BUG_ON_cond) assert(!(__BUG_ON_cond))
> +
> +/* Physical == Virtual */
> +#define virt_to_phys(p) ((unsigned long)p)
> +#define phys_to_virt(a) ((void *)(unsigned long)(a))
> +/* Page address: Virtual / 4K */
> +#define virt_to_page(p) ((struct page*)((virt_to_phys(p) / 4096) * \
> +                                       sizeof(struct page)))
> +#define offset_in_page(p) (((unsigned long)p) % 4096)
> +#define sg_phys(sg) ((sg->page_link & ~0x3) / sizeof(struct page) * 4096 + \
> +                    sg->offset)
> +static inline void sg_mark_end(struct scatterlist *sg)
> +{
> +       /*
> +        * Set termination bit, clear potential chain bit
> +        */
> +       sg->page_link |= 0x02;
> +       sg->page_link &= ~0x01;
> +}
> +static inline void sg_init_table(struct scatterlist *sgl, unsigned int nents)
> +{
> +       memset(sgl, 0, sizeof(*sgl) * nents);
> +       sg_mark_end(&sgl[nents - 1]);
> +}
> +static inline void sg_assign_page(struct scatterlist *sg, struct page *page)
> +{
> +       unsigned long page_link = sg->page_link & 0x3;
> +
> +       /*
> +        * In order for the low bit stealing approach to work, pages
> +        * must be aligned at a 32-bit boundary as a minimum.
> +        */
> +       BUG_ON((unsigned long) page & 0x03);
> +       sg->page_link = page_link | (unsigned long) page;
> +}
> +
> +static inline void sg_set_page(struct scatterlist *sg, struct page *page,
> +                              unsigned int len, unsigned int offset)
> +{
> +       sg_assign_page(sg, page);
> +       sg->offset = offset;
> +       sg->length = len;
> +}
> +
> +static inline void sg_set_buf(struct scatterlist *sg, const void *buf,
> +                             unsigned int buflen)
> +{
> +       sg_set_page(sg, virt_to_page(buf), buflen, offset_in_page(buf));
> +}
> +
> +static inline void sg_init_one(struct scatterlist *sg, const void *buf, unsigned int buflen)
> +{
> +       sg_init_table(sg, 1);
> +       sg_set_buf(sg, buf, buflen);
> +}
> +
> +typedef __u16 u16;
> +
> +typedef enum {
> +       GFP_KERNEL,
> +       GFP_ATOMIC,
> +} gfp_t;
> +typedef enum {
> +       IRQ_NONE,
> +       IRQ_HANDLED
> +} irqreturn_t;
> +
> +static inline void *kmalloc(size_t s, gfp_t gfp)
> +{
> +       return malloc(s);
> +}
> +
> +static inline void kfree(void *p)
> +{
> +       free(p);
> +}
> +
> +#define container_of(ptr, type, member) ({                     \
> +       const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
> +       (type *)( (char *)__mptr - offsetof(type,member) );})
> +
> +#define uninitialized_var(x) x = x
> +
> +# ifndef likely
> +#  define likely(x)    (__builtin_expect(!!(x), 1))
> +# endif
> +# ifndef unlikely
> +#  define unlikely(x)  (__builtin_expect(!!(x), 0))
> +# endif
> +
> +#define pr_err(format, ...) fprintf (stderr, format, ## __VA_ARGS__)
> +#ifdef DEBUG
> +#define pr_debug(format, ...) fprintf (stderr, format, ## __VA_ARGS__)
> +#else
> +#define pr_debug(format, ...) do {} while (0)
> +#endif
> +#define dev_err(dev, format, ...) fprintf (stderr, format, ## __VA_ARGS__)
> +#define dev_warn(dev, format, ...) fprintf (stderr, format, ## __VA_ARGS__)
> +
> +/* TODO: empty stubs for now. Broken but enough for virtio_ring.c */
> +#define list_add_tail(a, b) do {} while (0)
> +#define list_del(a) do {} while (0)
> +
> +#define BIT_WORD(nr)           ((nr) / BITS_PER_LONG)
> +#define BITS_PER_BYTE          8
> +#define BITS_PER_LONG (sizeof(long) * BITS_PER_BYTE)
> +#define BIT_MASK(nr)           (1UL << ((nr) % BITS_PER_LONG))
> +/* TODO: Not atomic as it should be:
> + * we don't use this for anything important. */
> +static inline void clear_bit(int nr, volatile unsigned long *addr)
> +{
> +       unsigned long mask = BIT_MASK(nr);
> +       unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
> +
> +       *p &= ~mask;
> +}
> +
> +static inline int test_bit(int nr, const volatile unsigned long *addr)
> +{
> +        return 1UL & (addr[BIT_WORD(nr)] >> (nr & (BITS_PER_LONG-1)));
> +}
> +
> +/* The only feature we care to support */
> +#define virtio_has_feature(dev, feature) \
> +       test_bit((feature), (dev)->features)
> +/* end of stubs */
> +
> +struct virtio_device {
> +       void *dev;
> +       unsigned long features[1];
> +};
> +
> +struct virtqueue {
> +       /* TODO: commented as list macros are empty stubs for now.
> +        * Broken but enough for virtio_ring.c
> +        * struct list_head list; */
> +       void (*callback)(struct virtqueue *vq);
> +       const char *name;
> +       struct virtio_device *vdev;
> +       void *priv;
> +};
> +
> +#define EXPORT_SYMBOL_GPL(__EXPORT_SYMBOL_GPL_name) \
> +       void __EXPORT_SYMBOL_GPL##__EXPORT_SYMBOL_GPL_name() { \
> +}
> +#define MODULE_LICENSE(__MODULE_LICENSE_value) \
> +       const char *__MODULE_LICENSE_name = __MODULE_LICENSE_value
> +
> +#define CONFIG_SMP
> +
> +#if defined(__i386__) || defined(__x86_64__)
> +#define barrier() asm volatile("" ::: "memory")
> +#define mb() __sync_synchronize()
> +
> +#define smp_mb()       mb()
> +# define smp_rmb()     barrier()
> +# define smp_wmb()     barrier()
> +#else
> +#error Please fill in barrier macros
> +#endif
> +
> +/* Interfaces exported by virtio_ring. */
> +int virtqueue_add_buf_gfp(struct virtqueue *vq,
> +                         struct scatterlist sg[],
> +                         unsigned int out_num,
> +                         unsigned int in_num,
> +                         void *data,
> +                         gfp_t gfp);
> +
> +static inline int virtqueue_add_buf(struct virtqueue *vq,
> +                                   struct scatterlist sg[],
> +                                   unsigned int out_num,
> +                                   unsigned int in_num,
> +                                   void *data)
> +{
> +       return virtqueue_add_buf_gfp(vq, sg, out_num, in_num, data, GFP_ATOMIC);
> +}
> +
> +void virtqueue_kick(struct virtqueue *vq);
> +
> +void *virtqueue_get_buf(struct virtqueue *vq, unsigned int *len);
> +
> +void virtqueue_disable_cb(struct virtqueue *vq);
> +
> +bool virtqueue_enable_cb(struct virtqueue *vq);
> +
> +void *virtqueue_detach_unused_buf(struct virtqueue *vq);
> +struct virtqueue *vring_new_virtqueue(unsigned int num,
> +                                     unsigned int vring_align,
> +                                     struct virtio_device *vdev,
> +                                     void *pages,
> +                                     void (*notify)(struct virtqueue *vq),
> +                                     void (*callback)(struct virtqueue *vq),
> +                                     const char *name);
> +void vring_del_virtqueue(struct virtqueue *vq);
> +
> +#endif
> diff --git a/tools/virtio/vhost_test/Makefile b/tools/virtio/vhost_test/Makefile
> new file mode 100644
> index 0000000..a1d35b8
> --- /dev/null
> +++ b/tools/virtio/vhost_test/Makefile
> @@ -0,0 +1,2 @@
> +obj-m += vhost_test.o
> +EXTRA_CFLAGS += -Idrivers/vhost
> diff --git a/tools/virtio/vhost_test/vhost_test.c b/tools/virtio/vhost_test/vhost_test.c
> new file mode 100644
> index 0000000..1873518
> --- /dev/null
> +++ b/tools/virtio/vhost_test/vhost_test.c
> @@ -0,0 +1 @@
> +#include "test.c"
> diff --git a/tools/virtio/virtio_test.c b/tools/virtio/virtio_test.c
> new file mode 100644
> index 0000000..808ae86
> --- /dev/null
> +++ b/tools/virtio/virtio_test.c
> @@ -0,0 +1,248 @@
> +#define _GNU_SOURCE
> +#include <getopt.h>
> +#include <string.h>
> +#include <poll.h>
> +#include <sys/eventfd.h>
> +#include <stdlib.h>
> +#include <assert.h>
> +#include <unistd.h>
> +#include <sys/ioctl.h>
> +#include <sys/stat.h>
> +#include <sys/types.h>
> +#include <fcntl.h>
> +#include <linux/vhost.h>
> +#include <linux/virtio.h>
> +#include <linux/virtio_ring.h>
> +#include "../../drivers/vhost/test.h"
> +
> +struct vq_info {
> +       int kick;
> +       int call;
> +       int num;
> +       int idx;
> +       void *ring;
> +       /* copy used for control */
> +       struct vring vring;
> +       struct virtqueue *vq;
> +};
> +
> +struct vdev_info {
> +       struct virtio_device vdev;
> +       int control;
> +       struct pollfd fds[1];
> +       struct vq_info vqs[1];
> +       int nvqs;
> +       void *buf;
> +       size_t buf_size;
> +       struct vhost_memory *mem;
> +};
> +
> +void vq_notify(struct virtqueue *vq)
> +{
> +       struct vq_info *info = vq->priv;
> +       unsigned long long v = 1;
> +       int r;
> +       r = write(info->kick, &v, sizeof v);
> +       assert(r == sizeof v);
> +}
> +
> +void vq_callback(struct virtqueue *vq)
> +{
> +}
> +
> +
> +void vhost_vq_setup(struct vdev_info *dev, struct vq_info *info)
> +{
> +       struct vhost_vring_state state = { .index = info->idx };
> +       struct vhost_vring_file file = { .index = info->idx };
> +       unsigned long long features = dev->vdev.features[0];
> +       struct vhost_vring_addr addr = {
> +               .index = info->idx,
> +               .desc_user_addr = (uint64_t)(unsigned long)info->vring.desc,
> +               .avail_user_addr = (uint64_t)(unsigned long)info->vring.avail,
> +               .used_user_addr = (uint64_t)(unsigned long)info->vring.used,
> +       };
> +       int r;
> +       r = ioctl(dev->control, VHOST_SET_FEATURES, &features);
> +       assert(r >= 0);
> +       state.num = info->vring.num;
> +       r = ioctl(dev->control, VHOST_SET_VRING_NUM, &state);
> +       assert(r >= 0);
> +       state.num = 0;
> +       r = ioctl(dev->control, VHOST_SET_VRING_BASE, &state);
> +       assert(r >= 0);
> +       r = ioctl(dev->control, VHOST_SET_VRING_ADDR, &addr);
> +       assert(r >= 0);
> +       file.fd = info->kick;
> +       r = ioctl(dev->control, VHOST_SET_VRING_KICK, &file);
> +       assert(r >= 0);
> +       file.fd = info->call;
> +       r = ioctl(dev->control, VHOST_SET_VRING_CALL, &file);
> +       assert(r >= 0);
> +}
> +
> +static void vq_info_add(struct vdev_info *dev, int num)
> +{
> +       struct vq_info *info = &dev->vqs[dev->nvqs];
> +       int r;
> +       info->idx = dev->nvqs;
> +       info->kick = eventfd(0, EFD_NONBLOCK);
> +       info->call = eventfd(0, EFD_NONBLOCK);
> +       r = posix_memalign(&info->ring, 4096, vring_size(num, 4096));
> +       assert(r >= 0);
> +       memset(info->ring, 0, vring_size(num, 4096));
> +       vring_init(&info->vring, num, info->ring, 4096);
> +       info->vq = vring_new_virtqueue(info->vring.num, 4096, &dev->vdev, info->ring,
> +                                      vq_notify, vq_callback, "test");
> +       assert(info->vq);
> +       info->vq->priv = info;
> +       vhost_vq_setup(dev, info);
> +       dev->fds[info->idx].fd = info->call;
> +       dev->fds[info->idx].events = POLLIN;
> +       dev->nvqs++;
> +}
> +
> +static void vdev_info_init(struct vdev_info* dev, unsigned long long features)
> +{
> +       int r;
> +       memset(dev, 0, sizeof *dev);
> +       dev->vdev.features[0] = features;
> +       dev->vdev.features[1] = features >> 32;
> +       dev->buf_size = 1024;
> +       dev->buf = malloc(dev->buf_size);
> +       assert(dev->buf);
> +        dev->control = open("/dev/vhost-test", O_RDWR);
> +       assert(dev->control >= 0);
> +       r = ioctl(dev->control, VHOST_SET_OWNER, NULL);
> +       assert(r >= 0);
> +       dev->mem = malloc(offsetof(struct vhost_memory, regions) +
> +                         sizeof dev->mem->regions[0]);
> +       assert(dev->mem);
> +       memset(dev->mem, 0, offsetof(struct vhost_memory, regions) +
> +                          sizeof dev->mem->regions[0]);
> +       dev->mem->nregions = 1;
> +       dev->mem->regions[0].guest_phys_addr = (long)dev->buf;
> +       dev->mem->regions[0].userspace_addr = (long)dev->buf;
> +       dev->mem->regions[0].memory_size = dev->buf_size;
> +       r = ioctl(dev->control, VHOST_SET_MEM_TABLE, dev->mem);
> +       assert(r >= 0);
> +}
> +
> +/* TODO: this is pretty bad: we get a cache line bounce
> + * for the wait queue on poll and another one on read,
> + * plus the read which is there just to clear the
> + * current state. */
> +static void wait_for_interrupt(struct vdev_info *dev)
> +{
> +       int i;
> +       unsigned long long val;
> +       poll(dev->fds, dev->nvqs, -1);
> +       for (i = 0; i < dev->nvqs; ++i)
> +               if (dev->fds[i].revents & POLLIN) {
> +                       read(dev->fds[i].fd, &val, sizeof val);
> +               }
> +}
> +
> +static void run_test(struct vdev_info *dev, struct vq_info *vq, int bufs)
> +{
> +       struct scatterlist sl;
> +       long started = 0, completed = 0;
> +       long completed_before;
> +       int r, test = 1;
> +       unsigned len;
> +       long long spurious = 0;
> +       r = ioctl(dev->control, VHOST_TEST_RUN, &test);
> +       assert(r >= 0);
> +       for (;;) {
> +               virtqueue_disable_cb(vq->vq);
> +               completed_before = completed;
> +               do {
> +                       if (started < bufs) {
> +                               sg_init_one(&sl, dev->buf, dev->buf_size);
> +                               r = virtqueue_add_buf(vq->vq, &sl, 1, 0,
> +                                                     dev->buf + started);
> +                               if (likely(r >= 0)) {
> +                                       ++started;
> +                                       virtqueue_kick(vq->vq);
> +                               }
> +                       } else
> +                               r = -1;
> +
> +                       /* Flush out completed bufs if any */
> +                       if (virtqueue_get_buf(vq->vq, &len)) {
> +                               ++completed;
> +                               r = 0;
> +                       }
> +
> +               } while (r >= 0);
> +               if (completed == completed_before)
> +                       ++spurious;
> +               assert(completed <= bufs);
> +               assert(started <= bufs);
> +               if (completed == bufs)
> +                       break;
> +               if (virtqueue_enable_cb(vq->vq)) {
> +                       wait_for_interrupt(dev);
> +               }
> +       }
> +       test = 0;
> +       r = ioctl(dev->control, VHOST_TEST_RUN, &test);
> +       assert(r >= 0);
> +       fprintf(stderr, "spurious wakeus: 0x%llx\n", spurious);
> +}
> +
> +const char optstring[] = "h";
> +const struct option longopts[] = {
> +       {
> +               .name = "help",
> +               .val = 'h',
> +       },
> +       {
> +               .name = "indirect",
> +               .val = 'I',
> +       },
> +       {
> +               .name = "no-indirect",
> +               .val = 'i',
> +       },
> +       {
> +       }
> +};
> +
> +static void help()
> +{
> +       fprintf(stderr, "Usage: virtio_test [--help] [--no-indirect]\n");
> +}
> +
> +int main(int argc, char **argv)
> +{
> +       struct vdev_info dev;
> +       unsigned long long features = 1ULL << VIRTIO_RING_F_INDIRECT_DESC;
> +       int o;
> +
> +       for (;;) {
> +               o = getopt_long(argc, argv, optstring, longopts, NULL);
> +               switch (o) {
> +               case -1:
> +                       goto done;
> +               case '?':
> +                       help();
> +                       exit(2);
> +               case 'h':
> +                       help();
> +                       goto done;
> +               case 'i':
> +                       features &= ~(1ULL << VIRTIO_RING_F_INDIRECT_DESC);
> +                       break;
> +               default:
> +                       assert(0);
> +                       break;
> +               }
> +       }
> +
> +done:
> +       vdev_info_init(&dev, features);
> +       vq_info_add(&dev, 256);
> +       run_test(&dev, &dev.vqs[0], 0x100000);
> +       return 0;
> +}
> --
> To unsubscribe from this list: send the line "unsubscribe kvm" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>



-- 
Regards,

Zhi Yong Wu

^ permalink raw reply

* [PATCH 23/62] x86: irq: Remove IRQF_DISABLED
From: Yong Zhang @ 2011-09-07  8:10 UTC (permalink / raw)
  To: linux-kernel
  Cc: Don Zickus, Venkatesh Pallipadi (Venki), Andy Lutomirski,
	Jeremy Fitzhardinge, Konrad Rzeszutek Wilk, x86, virtualization,
	Yong Zhang, Ingo Molnar, H. Peter Anvin, xen-devel, tglx, mingo
In-Reply-To: <1315383059-3673-1-git-send-email-yong.zhang0@gmail.com>

This flag is a NOOP and can be removed now.

Signed-off-by: Yong Zhang <yong.zhang0@gmail.com>
---
 arch/x86/include/asm/floppy.h |    4 ++--
 arch/x86/kernel/hpet.c        |    2 +-
 arch/x86/kernel/time.c        |    2 +-
 arch/x86/xen/smp.c            |    8 ++++----
 arch/x86/xen/spinlock.c       |    2 +-
 arch/x86/xen/time.c           |    5 ++---
 6 files changed, 11 insertions(+), 12 deletions(-)

diff --git a/arch/x86/include/asm/floppy.h b/arch/x86/include/asm/floppy.h
index dbe82a5..22bf4d6 100644
--- a/arch/x86/include/asm/floppy.h
+++ b/arch/x86/include/asm/floppy.h
@@ -145,10 +145,10 @@ static int fd_request_irq(void)
 {
 	if (can_use_virtual_dma)
 		return request_irq(FLOPPY_IRQ, floppy_hardint,
-				   IRQF_DISABLED, "floppy", NULL);
+				   0, "floppy", NULL);
 	else
 		return request_irq(FLOPPY_IRQ, floppy_interrupt,
-				   IRQF_DISABLED, "floppy", NULL);
+				   0, "floppy", NULL);
 }
 
 static unsigned long dma_mem_alloc(unsigned long size)
diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c
index 4aecc54..9d96096 100644
--- a/arch/x86/kernel/hpet.c
+++ b/arch/x86/kernel/hpet.c
@@ -515,7 +515,7 @@ static int hpet_setup_irq(struct hpet_dev *dev)
 {
 
 	if (request_irq(dev->irq, hpet_interrupt_handler,
-			IRQF_TIMER | IRQF_DISABLED | IRQF_NOBALANCING,
+			IRQF_TIMER | IRQF_NOBALANCING,
 			dev->name, dev))
 		return -1;
 
diff --git a/arch/x86/kernel/time.c b/arch/x86/kernel/time.c
index 5a64d05..e62386a 100644
--- a/arch/x86/kernel/time.c
+++ b/arch/x86/kernel/time.c
@@ -70,7 +70,7 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id)
 
 static struct irqaction irq0  = {
 	.handler = timer_interrupt,
-	.flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_IRQPOLL | IRQF_TIMER,
+	.flags = IRQF_NOBALANCING | IRQF_IRQPOLL | IRQF_TIMER,
 	.name = "timer"
 };
 
diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c
index e79dbb9..b20b94d 100644
--- a/arch/x86/xen/smp.c
+++ b/arch/x86/xen/smp.c
@@ -99,7 +99,7 @@ static int xen_smp_intr_init(unsigned int cpu)
 	rc = bind_ipi_to_irqhandler(XEN_RESCHEDULE_VECTOR,
 				    cpu,
 				    xen_reschedule_interrupt,
-				    IRQF_DISABLED|IRQF_PERCPU|IRQF_NOBALANCING,
+				    IRQF_PERCPU|IRQF_NOBALANCING,
 				    resched_name,
 				    NULL);
 	if (rc < 0)
@@ -110,7 +110,7 @@ static int xen_smp_intr_init(unsigned int cpu)
 	rc = bind_ipi_to_irqhandler(XEN_CALL_FUNCTION_VECTOR,
 				    cpu,
 				    xen_call_function_interrupt,
-				    IRQF_DISABLED|IRQF_PERCPU|IRQF_NOBALANCING,
+				    IRQF_PERCPU|IRQF_NOBALANCING,
 				    callfunc_name,
 				    NULL);
 	if (rc < 0)
@@ -119,7 +119,7 @@ static int xen_smp_intr_init(unsigned int cpu)
 
 	debug_name = kasprintf(GFP_KERNEL, "debug%d", cpu);
 	rc = bind_virq_to_irqhandler(VIRQ_DEBUG, cpu, xen_debug_interrupt,
-				     IRQF_DISABLED | IRQF_PERCPU | IRQF_NOBALANCING,
+				     IRQF_PERCPU | IRQF_NOBALANCING,
 				     debug_name, NULL);
 	if (rc < 0)
 		goto fail;
@@ -129,7 +129,7 @@ static int xen_smp_intr_init(unsigned int cpu)
 	rc = bind_ipi_to_irqhandler(XEN_CALL_FUNCTION_SINGLE_VECTOR,
 				    cpu,
 				    xen_call_function_single_interrupt,
-				    IRQF_DISABLED|IRQF_PERCPU|IRQF_NOBALANCING,
+				    IRQF_PERCPU|IRQF_NOBALANCING,
 				    callfunc_name,
 				    NULL);
 	if (rc < 0)
diff --git a/arch/x86/xen/spinlock.c b/arch/x86/xen/spinlock.c
index cc9b1e1..27882f5 100644
--- a/arch/x86/xen/spinlock.c
+++ b/arch/x86/xen/spinlock.c
@@ -354,7 +354,7 @@ void __cpuinit xen_init_lock_cpu(int cpu)
 	irq = bind_ipi_to_irqhandler(XEN_SPIN_UNLOCK_VECTOR,
 				     cpu,
 				     dummy_handler,
-				     IRQF_DISABLED|IRQF_PERCPU|IRQF_NOBALANCING,
+				     IRQF_PERCPU|IRQF_NOBALANCING,
 				     name,
 				     NULL);
 
diff --git a/arch/x86/xen/time.c b/arch/x86/xen/time.c
index 5158c50..f164ccc 100644
--- a/arch/x86/xen/time.c
+++ b/arch/x86/xen/time.c
@@ -393,9 +393,8 @@ void xen_setup_timer(int cpu)
 		name = "<timer kasprintf failed>";
 
 	irq = bind_virq_to_irqhandler(VIRQ_TIMER, cpu, xen_timer_interrupt,
-				      IRQF_DISABLED|IRQF_PERCPU|
-				      IRQF_NOBALANCING|IRQF_TIMER|
-				      IRQF_FORCE_RESUME,
+				      IRQF_PERCPU|IRQF_NOBALANCING|
+				      IRQF_TIMER|IRQF_FORCE_RESUME,
 				      name, NULL);
 
 	evt = &per_cpu(xen_clock_events, cpu);
-- 
1.7.4.1

^ permalink raw reply related

* [PATCH 59/62] xen: irq: Remove IRQF_DISABLED
From: Yong Zhang @ 2011-09-07  8:10 UTC (permalink / raw)
  To: linux-kernel
  Cc: xen-devel, Konrad Rzeszutek Wilk, virtualization,
	Jeremy Fitzhardinge, tglx, mingo
In-Reply-To: <1315383059-3673-1-git-send-email-yong.zhang0@gmail.com>

This flag is a NOOP and can be removed now.

Signed-off-by: Yong Zhang <yong.zhang0@gmail.com>
---
 drivers/xen/evtchn.c       |    2 +-
 drivers/xen/platform-pci.c |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/xen/evtchn.c b/drivers/xen/evtchn.c
index dbc13e9..95e2507 100644
--- a/drivers/xen/evtchn.c
+++ b/drivers/xen/evtchn.c
@@ -265,7 +265,7 @@ static int evtchn_bind_to_user(struct per_user_data *u, int port)
 	set_port_user(port, u);
 	set_port_enabled(port, true); /* start enabled */
 
-	rc = bind_evtchn_to_irqhandler(port, evtchn_interrupt, IRQF_DISABLED,
+	rc = bind_evtchn_to_irqhandler(port, evtchn_interrupt, 0,
 				       u->name, (void *)(unsigned long)port);
 	if (rc >= 0)
 		rc = 0;
diff --git a/drivers/xen/platform-pci.c b/drivers/xen/platform-pci.c
index 319dd0a..482beff 100644
--- a/drivers/xen/platform-pci.c
+++ b/drivers/xen/platform-pci.c
@@ -84,7 +84,7 @@ static irqreturn_t do_hvm_evtchn_intr(int irq, void *dev_id)
 static int xen_allocate_irq(struct pci_dev *pdev)
 {
 	return request_irq(pdev->irq, do_hvm_evtchn_intr,
-			IRQF_DISABLED | IRQF_NOBALANCING | IRQF_TRIGGER_RISING,
+			IRQF_NOBALANCING | IRQF_TRIGGER_RISING,
 			"xen-platform-pci", pdev);
 }
 
-- 
1.7.4.1

^ permalink raw reply related

* [RFC v2 0/2] virtio: Support releasing lock during kick
From: Stefan Hajnoczi @ 2011-09-07 13:51 UTC (permalink / raw)
  To: virtualization
  Cc: Khoa Huynh, Christoph Hellwig, Stefan Hajnoczi,
	Michael S. Tsirkin

This patch allows virtio-blk to release its block queue lock while kicking the
host.  This improves scalability on SMP guests who would otherwise spin on the
lock while another vCPU is kicking the host.

This approach can be used for other virtio devices too.  It simply splits the
virtqueue_kick() operation into a prepare step which requires that the lock be
held and the actual notify step which may be performed without the lock.
Existing virtio drivers may continue to use the virtqueue_kick() interface
which now does the prepare and notify steps internally.

I am sending this out as RFC because further performance benchmarking is
required.  Although we have seen good results in the past, gathering number on
a wider range of machines and verifying that there is no regression would be
helpful.

Stefan Hajnoczi (2):
  virtio_ring: split virtqueue_kick prepare/notify
  virtio_blk: unlock vblk->lock during kick

 drivers/block/virtio_blk.c   |   10 ++++++++--
 drivers/virtio/virtio_ring.c |   28 +++++++++++++++++++++-------
 include/linux/virtio.h       |   13 +++++++++++++
 3 files changed, 42 insertions(+), 9 deletions(-)

-- 
1.7.5.4

^ permalink raw reply

* [PATCH v2 1/2] virtio_ring: split virtqueue_kick prepare/notify
From: Stefan Hajnoczi @ 2011-09-07 13:51 UTC (permalink / raw)
  To: virtualization
  Cc: Khoa Huynh, Christoph Hellwig, Stefan Hajnoczi,
	Michael S. Tsirkin
In-Reply-To: <1315403501-12457-1-git-send-email-stefanha@linux.vnet.ibm.com>

The virtqueue_kick() operation really has two phases and should be split
so that devices hold locks only when necessary.  This patch splits
virtqueue_kick() into two virtqueue_kick_prepare() and
virtqueue_kick_notify().

virtqueue_kick_prepare() updates the vring and checks whether the host
needs to be notified.  This function must be executed with a lock held
to protect the vring.

virtqueue_kick_notify() notifies the host that the vring has new
buffers.  This function may be executed without holding a lock
protecting the vring.

Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
---
 drivers/virtio/virtio_ring.c |   28 +++++++++++++++++++++-------
 include/linux/virtio.h       |   13 +++++++++++++
 2 files changed, 34 insertions(+), 7 deletions(-)

diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
index 68b9136..7d059f7 100644
--- a/drivers/virtio/virtio_ring.c
+++ b/drivers/virtio/virtio_ring.c
@@ -237,10 +237,12 @@ add_head:
 }
 EXPORT_SYMBOL_GPL(virtqueue_add_buf_gfp);
 
-void virtqueue_kick(struct virtqueue *_vq)
+bool virtqueue_kick_prepare(struct virtqueue *_vq)
 {
 	struct vring_virtqueue *vq = to_vvq(_vq);
 	u16 new, old;
+	bool r;
+
 	START_USE(vq);
 	/* Descriptors and available array need to be set before we expose the
 	 * new available array entries. */
@@ -253,13 +255,25 @@ void virtqueue_kick(struct virtqueue *_vq)
 	/* Need to update avail index before checking if we should notify */
 	virtio_mb();
 
-	if (vq->event ?
-	    vring_need_event(vring_avail_event(&vq->vring), new, old) :
-	    !(vq->vring.used->flags & VRING_USED_F_NO_NOTIFY))
-		/* Prod other side to tell it about changes. */
-		vq->notify(&vq->vq);
-
+	if (vq->event)
+		r = vring_need_event(vring_avail_event(&vq->vring), new, old);
+	else
+		r = !(vq->vring.used->flags & VRING_USED_F_NO_NOTIFY);
 	END_USE(vq);
+	return r;
+}
+EXPORT_SYMBOL_GPL(virtqueue_kick_prepare);
+
+void virtqueue_kick_notify(struct virtqueue *_vq)
+{
+	to_vvq(_vq)->notify(_vq);
+}
+EXPORT_SYMBOL_GPL(virtqueue_kick_notify);
+
+void virtqueue_kick(struct virtqueue *_vq)
+{
+	if (virtqueue_kick_prepare(_vq))
+		virtqueue_kick_notify(_vq);
 }
 EXPORT_SYMBOL_GPL(virtqueue_kick);
 
diff --git a/include/linux/virtio.h b/include/linux/virtio.h
index 7108857..65536cb 100644
--- a/include/linux/virtio.h
+++ b/include/linux/virtio.h
@@ -35,9 +35,18 @@ struct virtqueue {
  *	data: the token identifying the buffer.
  *	gfp: how to do memory allocations (if necessary).
  *      Returns remaining capacity of queue (sg segments) or a negative error.
+ * virtqueue_kick_prepare: update after add_buf and check if kick necessary
+ *	vq: the struct virtqueue
+ *	After one or more add_buf calls, invoke this to check whether kick is
+ *	necessary.
+ * virtqueue_kick_notify: kick the other side
+ *	vq: the struct virtqueue
+ *	Normally virtqueue_kick_prepare is called before this.  Can be done in
+ *	parallel with add_buf/get_buf.
  * virtqueue_kick: update after add_buf
  *	vq: the struct virtqueue
  *	After one or more add_buf calls, invoke this to kick the other side.
+ *	Uses virtqueue_kick_prepare and virtqueue_kick_notify internally.
  * virtqueue_get_buf: get the next used buffer
  *	vq: the struct virtqueue we're talking about.
  *	len: the length written into the buffer
@@ -85,6 +94,10 @@ static inline int virtqueue_add_buf(struct virtqueue *vq,
 	return virtqueue_add_buf_gfp(vq, sg, out_num, in_num, data, GFP_ATOMIC);
 }
 
+bool virtqueue_kick_prepare(struct virtqueue *vq);
+
+void virtqueue_kick_notify(struct virtqueue *vq);
+
 void virtqueue_kick(struct virtqueue *vq);
 
 void *virtqueue_get_buf(struct virtqueue *vq, unsigned int *len);
-- 
1.7.5.4

^ permalink raw reply related

* [PATCH v2 2/2] virtio_blk: unlock vblk->lock during kick
From: Stefan Hajnoczi @ 2011-09-07 13:51 UTC (permalink / raw)
  To: virtualization
  Cc: Khoa Huynh, Christoph Hellwig, Stefan Hajnoczi,
	Michael S. Tsirkin
In-Reply-To: <1315403501-12457-1-git-send-email-stefanha@linux.vnet.ibm.com>

Holding the vblk->lock across kick causes poor scalability in SMP
guests.  If one CPU is doing virtqueue kick and another CPU touches the
vblk->lock it will have to spin until virtqueue kick completes.

This typically results in high system CPU utilization in SMP guests that
are running multithreaded I/O-bound workloads.

Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
---
 drivers/block/virtio_blk.c |   10 ++++++++--
 1 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c
index 079c088..c2bf0a9 100644
--- a/drivers/block/virtio_blk.c
+++ b/drivers/block/virtio_blk.c
@@ -193,8 +193,14 @@ static void do_virtblk_request(struct request_queue *q)
 		issued++;
 	}
 
-	if (issued)
-		virtqueue_kick(vblk->vq);
+	if (!issued)
+		return;
+
+	if (virtqueue_kick_prepare(vblk->vq)) {
+		spin_unlock(&vblk->lock);
+		virtqueue_kick_notify(vblk->vq);
+		spin_lock(&vblk->lock);
+	}
 }
 
 /* return id (s/n) string for *disk to *id_str
-- 
1.7.5.4

^ permalink raw reply related

* Re: [RFC v2 0/2] virtio: Support releasing lock during kick
From: Michael S. Tsirkin @ 2011-09-07 14:01 UTC (permalink / raw)
  To: Stefan Hajnoczi; +Cc: Khoa Huynh, Christoph Hellwig, virtualization
In-Reply-To: <1315403501-12457-1-git-send-email-stefanha@linux.vnet.ibm.com>

On Wed, Sep 07, 2011 at 02:51:39PM +0100, Stefan Hajnoczi wrote:
> This patch allows virtio-blk to release its block queue lock while kicking the
> host.  This improves scalability on SMP guests who would otherwise spin on the
> lock while another vCPU is kicking the host.
> 
> This approach can be used for other virtio devices too.  It simply splits the
> virtqueue_kick() operation into a prepare step which requires that the lock be
> held and the actual notify step which may be performed without the lock.
> Existing virtio drivers may continue to use the virtqueue_kick() interface
> which now does the prepare and notify steps internally.
> 
> I am sending this out as RFC because further performance benchmarking is
> required.  Although we have seen good results in the past, gathering number on
> a wider range of machines and verifying that there is no regression would be
> helpful.

Makes sense to me.
Acked-by: Michael S. Tsirkin <mst@redhat.com>

> Stefan Hajnoczi (2):
>   virtio_ring: split virtqueue_kick prepare/notify
>   virtio_blk: unlock vblk->lock during kick
> 
>  drivers/block/virtio_blk.c   |   10 ++++++++--
>  drivers/virtio/virtio_ring.c |   28 +++++++++++++++++++++-------
>  include/linux/virtio.h       |   13 +++++++++++++
>  3 files changed, 42 insertions(+), 9 deletions(-)
> 
> -- 
> 1.7.5.4

^ permalink raw reply

* [PATCH 1/1] Staging: hv: Integrate the time source driver with Hyper-V detection code
From: K. Y. Srinivasan @ 2011-09-07 22:25 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, virtualization
  Cc: K. Y. Srinivasan, Haiyang Zhang

The Hyper-V timesource driver is best integrated with Hyper-V detection code
since: (a) Linux guests running on Hyper-V need this timesource and (b)
by integrating with Hyper-V detection, we could significantly  minimize the
code in the timesource driver.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 arch/x86/kernel/cpu/mshyperv.c     |   24 +++++++++
 drivers/staging/hv/Makefile        |    2 +-
 drivers/staging/hv/hv_timesource.c |  101 ------------------------------------
 3 files changed, 25 insertions(+), 102 deletions(-)
 delete mode 100644 drivers/staging/hv/hv_timesource.c

diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
index d944bf6..c97f88d 100644
--- a/arch/x86/kernel/cpu/mshyperv.c
+++ b/arch/x86/kernel/cpu/mshyperv.c
@@ -11,6 +11,8 @@
  */
 
 #include <linux/types.h>
+#include <linux/time.h>
+#include <linux/clocksource.h>
 #include <linux/module.h>
 #include <asm/processor.h>
 #include <asm/hypervisor.h>
@@ -36,6 +38,25 @@ static bool __init ms_hyperv_platform(void)
 		!memcmp("Microsoft Hv", hyp_signature, 12);
 }
 
+static cycle_t read_hv_clock(struct clocksource *arg)
+{
+	cycle_t current_tick;
+	/*
+	 * Read the partition counter to get the current tick count. This count
+	 * is set to 0 when the partition is created and is incremented in
+	 * 100 nanosecond units.
+	 */
+	rdmsrl(HV_X64_MSR_TIME_REF_COUNT, current_tick);
+	return current_tick;
+}
+
+static struct clocksource hyperv_cs = {
+	.name           = "hyperv_clocksource",
+	.rating         = 400, /* use this when running on Hyperv*/
+	.read           = read_hv_clock,
+	.mask           = CLOCKSOURCE_MASK(64),
+};
+
 static void __init ms_hyperv_init_platform(void)
 {
 	/*
@@ -46,6 +67,9 @@ static void __init ms_hyperv_init_platform(void)
 
 	printk(KERN_INFO "HyperV: features 0x%x, hints 0x%x\n",
 	       ms_hyperv.features, ms_hyperv.hints);
+
+
+	clocksource_register_hz(&hyperv_cs, NSEC_PER_SEC/100);
 }
 
 const __refconst struct hypervisor_x86 x86_hyper_ms_hyperv = {
diff --git a/drivers/staging/hv/Makefile b/drivers/staging/hv/Makefile
index bd176b1..3e0d7e6 100644
--- a/drivers/staging/hv/Makefile
+++ b/drivers/staging/hv/Makefile
@@ -1,4 +1,4 @@
-obj-$(CONFIG_HYPERV)		+= hv_vmbus.o hv_timesource.o
+obj-$(CONFIG_HYPERV)		+= hv_vmbus.o
 obj-$(CONFIG_HYPERV_STORAGE)	+= hv_storvsc.o
 obj-$(CONFIG_HYPERV_NET)	+= hv_netvsc.o
 obj-$(CONFIG_HYPERV_UTILS)	+= hv_utils.o
diff --git a/drivers/staging/hv/hv_timesource.c b/drivers/staging/hv/hv_timesource.c
deleted file mode 100644
index 2b0f9aa..0000000
--- a/drivers/staging/hv/hv_timesource.c
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * A clocksource for Linux running on HyperV.
- *
- *
- * Copyright (C) 2010, Novell, Inc.
- * Author : K. Y. Srinivasan <ksrinivasan@novell.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/clocksource.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/dmi.h>
-#include <asm/hyperv.h>
-#include <asm/mshyperv.h>
-#include <asm/hypervisor.h>
-
-#define HV_CLOCK_SHIFT	22
-
-static cycle_t read_hv_clock(struct clocksource *arg)
-{
-	cycle_t current_tick;
-	/*
-	 * Read the partition counter to get the current tick count. This count
-	 * is set to 0 when the partition is created and is incremented in
-	 * 100 nanosecond units.
-	 */
-	rdmsrl(HV_X64_MSR_TIME_REF_COUNT, current_tick);
-	return current_tick;
-}
-
-static struct clocksource hyperv_cs = {
-	.name           = "hyperv_clocksource",
-	.rating         = 400, /* use this when running on Hyperv*/
-	.read           = read_hv_clock,
-	.mask           = CLOCKSOURCE_MASK(64),
-	/*
-	 * The time ref counter in HyperV is in 100ns units.
-	 * The definition of mult is:
-	 * mult/2^shift = ns/cyc = 100
-	 * mult = (100 << shift)
-	 */
-	.mult           = (100 << HV_CLOCK_SHIFT),
-	.shift          = HV_CLOCK_SHIFT,
-};
-
-static const struct dmi_system_id __initconst
-hv_timesource_dmi_table[] __maybe_unused  = {
-	{
-		.ident = "Hyper-V",
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "Virtual Machine"),
-			DMI_MATCH(DMI_BOARD_NAME, "Virtual Machine"),
-		},
-	},
-	{ },
-};
-MODULE_DEVICE_TABLE(dmi, hv_timesource_dmi_table);
-
-static const struct pci_device_id __initconst
-hv_timesource_pci_table[] __maybe_unused = {
-	{ PCI_DEVICE(0x1414, 0x5353) }, /* VGA compatible controller */
-	{ 0 }
-};
-MODULE_DEVICE_TABLE(pci, hv_timesource_pci_table);
-
-
-static int __init init_hv_clocksource(void)
-{
-	if ((x86_hyper != &x86_hyper_ms_hyperv) ||
-		!(ms_hyperv.features & HV_X64_MSR_TIME_REF_COUNT_AVAILABLE))
-		return -ENODEV;
-
-	if (!dmi_check_system(hv_timesource_dmi_table))
-		return -ENODEV;
-
-	pr_info("Registering HyperV clock source\n");
-	return clocksource_register(&hyperv_cs);
-}
-
-module_init(init_hv_clocksource);
-MODULE_DESCRIPTION("HyperV based clocksource");
-MODULE_AUTHOR("K. Y. Srinivasan <ksrinivasan@novell.com>");
-MODULE_LICENSE("GPL");
-- 
1.7.4.1

^ permalink raw reply related

* [PATCH 0000/0025] Staging: hv: Driver cleanup
From: K. Y. Srinivasan @ 2011-09-08 14:24 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, virtualization

Address Greg's VmBus audit comments:

	1) Leverage driver_data field in struct hv_vmbus_device_id to
	   simplify driver code.

	2) Make the util driver conform to the Linux Driver Model.

	3) Get rid of the ext field in struct hv_device by using the
	   driver specific data functionality.

	4) Other general cleanup.


Regards,

K. Y

^ permalink raw reply

* [PATCH 01/25] Staging: hv: vmbus: Rename vmbus_child_device_create
From: K. Y. Srinivasan @ 2011-09-08 14:24 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, virtualization; +Cc: Haiyang Zhang
In-Reply-To: <1315491843-9513-1-git-send-email-kys@microsoft.com>

The vmbus devices are NOT child devices; rename vmbus_child_device_create
to reflect this.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 drivers/staging/hv/channel_mgmt.c |    2 +-
 drivers/staging/hv/hyperv_vmbus.h |    2 +-
 drivers/staging/hv/vmbus_drv.c    |    4 ++--
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/staging/hv/channel_mgmt.c b/drivers/staging/hv/channel_mgmt.c
index 11beb41..f99b944 100644
--- a/drivers/staging/hv/channel_mgmt.c
+++ b/drivers/staging/hv/channel_mgmt.c
@@ -383,7 +383,7 @@ static void vmbus_process_offer(struct work_struct *work)
 	 * We need to set the DeviceObject field before calling
 	 * vmbus_child_dev_add()
 	 */
-	newchannel->device_obj = vmbus_child_device_create(
+	newchannel->device_obj = vmbus_device_create(
 		&newchannel->offermsg.offer.if_type,
 		&newchannel->offermsg.offer.if_instance,
 		newchannel);
diff --git a/drivers/staging/hv/hyperv_vmbus.h b/drivers/staging/hv/hyperv_vmbus.h
index 16ca90d..e97e2cf 100644
--- a/drivers/staging/hv/hyperv_vmbus.h
+++ b/drivers/staging/hv/hyperv_vmbus.h
@@ -601,7 +601,7 @@ extern struct vmbus_connection vmbus_connection;
 
 /* General vmbus interface */
 
-struct hv_device *vmbus_child_device_create(uuid_le *type,
+struct hv_device *vmbus_device_create(uuid_le *type,
 					 uuid_le *instance,
 					 struct vmbus_channel *channel);
 
diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c
index c0f3b7a..382baee 100644
--- a/drivers/staging/hv/vmbus_drv.c
+++ b/drivers/staging/hv/vmbus_drv.c
@@ -594,10 +594,10 @@ void vmbus_driver_unregister(struct hv_driver *hv_driver)
 EXPORT_SYMBOL_GPL(vmbus_driver_unregister);
 
 /*
- * vmbus_child_device_create - Creates and registers a new child device
+ * vmbus_device_create - Creates and registers a new child device
  * on the vmbus.
  */
-struct hv_device *vmbus_child_device_create(uuid_le *type,
+struct hv_device *vmbus_device_create(uuid_le *type,
 					    uuid_le *instance,
 					    struct vmbus_channel *channel)
 {
-- 
1.7.4.1

^ permalink raw reply related

* [PATCH 02/25] Staging: hv: vmbus: Rename vmbus_child_device_register
From: K. Y. Srinivasan @ 2011-09-08 14:24 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, virtualization; +Cc: Haiyang Zhang
In-Reply-To: <1315491876-9554-1-git-send-email-kys@microsoft.com>

The vmbus devices are NOT child devices; rename vmbus_child_device_register
to reflect this.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 drivers/staging/hv/channel_mgmt.c |    2 +-
 drivers/staging/hv/hyperv_vmbus.h |    2 +-
 drivers/staging/hv/vmbus_drv.c    |    4 ++--
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/staging/hv/channel_mgmt.c b/drivers/staging/hv/channel_mgmt.c
index f99b944..a927046 100644
--- a/drivers/staging/hv/channel_mgmt.c
+++ b/drivers/staging/hv/channel_mgmt.c
@@ -393,7 +393,7 @@ static void vmbus_process_offer(struct work_struct *work)
 	 * binding which eventually invokes the device driver's AddDevice()
 	 * method.
 	 */
-	ret = vmbus_child_device_register(newchannel->device_obj);
+	ret = vmbus_device_register(newchannel->device_obj);
 	if (ret != 0) {
 		pr_err("unable to add child device object (relid %d)\n",
 			   newchannel->offermsg.child_relid);
diff --git a/drivers/staging/hv/hyperv_vmbus.h b/drivers/staging/hv/hyperv_vmbus.h
index e97e2cf..b2dfcd6 100644
--- a/drivers/staging/hv/hyperv_vmbus.h
+++ b/drivers/staging/hv/hyperv_vmbus.h
@@ -605,7 +605,7 @@ struct hv_device *vmbus_device_create(uuid_le *type,
 					 uuid_le *instance,
 					 struct vmbus_channel *channel);
 
-int vmbus_child_device_register(struct hv_device *child_device_obj);
+int vmbus_device_register(struct hv_device *child_device_obj);
 void vmbus_child_device_unregister(struct hv_device *device_obj);
 
 /* static void */
diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c
index 382baee..6d54ea1 100644
--- a/drivers/staging/hv/vmbus_drv.c
+++ b/drivers/staging/hv/vmbus_drv.c
@@ -619,9 +619,9 @@ struct hv_device *vmbus_device_create(uuid_le *type,
 }
 
 /*
- * vmbus_child_device_register - Register the child device
+ * vmbus_device_register - Register the child device
  */
-int vmbus_child_device_register(struct hv_device *child_device_obj)
+int vmbus_device_register(struct hv_device *child_device_obj)
 {
 	int ret = 0;
 
-- 
1.7.4.1

^ permalink raw reply related

* [PATCH 03/25] Staging: hv: vmbus: Rename vmbus_child_device_unregister
From: K. Y. Srinivasan @ 2011-09-08 14:24 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, virtualization
  Cc: K. Y. Srinivasan, Haiyang Zhang
In-Reply-To: <1315491876-9554-1-git-send-email-kys@microsoft.com>

The vmbus devices are NOT child devices; rename vmbus_child_device_unregister
to reflect this.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 drivers/staging/hv/channel_mgmt.c |    2 +-
 drivers/staging/hv/hyperv_vmbus.h |    2 +-
 drivers/staging/hv/vmbus_drv.c    |    4 ++--
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/staging/hv/channel_mgmt.c b/drivers/staging/hv/channel_mgmt.c
index a927046..60ce1d1 100644
--- a/drivers/staging/hv/channel_mgmt.c
+++ b/drivers/staging/hv/channel_mgmt.c
@@ -333,7 +333,7 @@ static void vmbus_process_rescind_offer(struct work_struct *work)
 						     struct vmbus_channel,
 						     work);
 
-	vmbus_child_device_unregister(channel->device_obj);
+	vmbus_device_unregister(channel->device_obj);
 }
 
 /*
diff --git a/drivers/staging/hv/hyperv_vmbus.h b/drivers/staging/hv/hyperv_vmbus.h
index b2dfcd6..3d2d836 100644
--- a/drivers/staging/hv/hyperv_vmbus.h
+++ b/drivers/staging/hv/hyperv_vmbus.h
@@ -606,7 +606,7 @@ struct hv_device *vmbus_device_create(uuid_le *type,
 					 struct vmbus_channel *channel);
 
 int vmbus_device_register(struct hv_device *child_device_obj);
-void vmbus_child_device_unregister(struct hv_device *device_obj);
+void vmbus_device_unregister(struct hv_device *device_obj);
 
 /* static void */
 /* VmbusChildDeviceDestroy( */
diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c
index 6d54ea1..375e451 100644
--- a/drivers/staging/hv/vmbus_drv.c
+++ b/drivers/staging/hv/vmbus_drv.c
@@ -650,10 +650,10 @@ int vmbus_device_register(struct hv_device *child_device_obj)
 }
 
 /*
- * vmbus_child_device_unregister - Remove the specified child device
+ * vmbus_device_unregister - Remove the specified child device
  * from the vmbus.
  */
-void vmbus_child_device_unregister(struct hv_device *device_obj)
+void vmbus_device_unregister(struct hv_device *device_obj)
 {
 	/*
 	 * Kick off the process of unregistering the device.
-- 
1.7.4.1

^ permalink raw reply related

* [PATCH 04/25] Staging: hv: vmbus: Cleanup dated comments in channel_mgmt.c
From: K. Y. Srinivasan @ 2011-09-08 14:24 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, virtualization
  Cc: K. Y. Srinivasan, Haiyang Zhang
In-Reply-To: <1315491876-9554-1-git-send-email-kys@microsoft.com>

Cleanup dated comments in channel_mgmt.c.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 drivers/staging/hv/channel_mgmt.c |    3 ---
 1 files changed, 0 insertions(+), 3 deletions(-)

diff --git a/drivers/staging/hv/channel_mgmt.c b/drivers/staging/hv/channel_mgmt.c
index 60ce1d1..c68e5fa 100644
--- a/drivers/staging/hv/channel_mgmt.c
+++ b/drivers/staging/hv/channel_mgmt.c
@@ -433,9 +433,6 @@ static void vmbus_process_offer(struct work_struct *work)
 /*
  * vmbus_onoffer - Handler for channel offers from vmbus in parent partition.
  *
- * We ignore all offers except network and storage offers. For each network and
- * storage offers, we create a channel object and queue a work item to the
- * channel object to process the offer synchronously
  */
 static void vmbus_onoffer(struct vmbus_channel_message_header *hdr)
 {
-- 
1.7.4.1

^ permalink raw reply related

* [PATCH 05/25] Staging: hv: vmbus: Change the signature of struct hv_driver probe function
From: K. Y. Srinivasan @ 2011-09-08 14:24 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, virtualization; +Cc: Haiyang Zhang
In-Reply-To: <1315491876-9554-1-git-send-email-kys@microsoft.com>

In preparation to leveraging the driver_data field in struct
hv_vmbus_device_id, change the signature of struct hv_driver probe function.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 drivers/staging/hv/hv_mouse.c    |    3 ++-
 drivers/staging/hv/hv_util.c     |    3 ++-
 drivers/staging/hv/hyperv.h      |    2 +-
 drivers/staging/hv/netvsc_drv.c  |    3 ++-
 drivers/staging/hv/storvsc_drv.c |    3 ++-
 drivers/staging/hv/vmbus_drv.c   |    8 +++++++-
 6 files changed, 16 insertions(+), 6 deletions(-)

diff --git a/drivers/staging/hv/hv_mouse.c b/drivers/staging/hv/hv_mouse.c
index dbb04ee..5ff8a03 100644
--- a/drivers/staging/hv/hv_mouse.c
+++ b/drivers/staging/hv/hv_mouse.c
@@ -823,7 +823,8 @@ static int mousevsc_on_device_remove(struct hv_device *device)
 }
 
 
-static int mousevsc_probe(struct hv_device *dev)
+static int mousevsc_probe(struct hv_device *dev,
+			const struct hv_vmbus_device_id *dev_id)
 {
 	int ret = 0;
 
diff --git a/drivers/staging/hv/hv_util.c b/drivers/staging/hv/hv_util.c
index 6039217..d9460fdd 100644
--- a/drivers/staging/hv/hv_util.c
+++ b/drivers/staging/hv/hv_util.c
@@ -239,7 +239,8 @@ static void heartbeat_onchannelcallback(void *context)
  * The devices managed by the util driver don't need any additional
  * setup.
  */
-static int util_probe(struct hv_device *dev)
+static int util_probe(struct hv_device *dev,
+			const struct hv_vmbus_device_id *dev_id)
 {
 	return 0;
 }
diff --git a/drivers/staging/hv/hyperv.h b/drivers/staging/hv/hyperv.h
index c249811..caa3a7b 100644
--- a/drivers/staging/hv/hyperv.h
+++ b/drivers/staging/hv/hyperv.h
@@ -810,7 +810,7 @@ struct hv_driver {
 
 	struct device_driver driver;
 
-	int (*probe)(struct hv_device *);
+	int (*probe)(struct hv_device *, const struct hv_vmbus_device_id *);
 	int (*remove)(struct hv_device *);
 	void (*shutdown)(struct hv_device *);
 
diff --git a/drivers/staging/hv/netvsc_drv.c b/drivers/staging/hv/netvsc_drv.c
index 30b9c80..d06cde2 100644
--- a/drivers/staging/hv/netvsc_drv.c
+++ b/drivers/staging/hv/netvsc_drv.c
@@ -329,7 +329,8 @@ static void netvsc_send_garp(struct work_struct *w)
 }
 
 
-static int netvsc_probe(struct hv_device *dev)
+static int netvsc_probe(struct hv_device *dev,
+			const struct hv_vmbus_device_id *dev_id)
 {
 	struct net_device *net = NULL;
 	struct net_device_context *net_device_ctx;
diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c
index b0c4e56..fff1e5b 100644
--- a/drivers/staging/hv/storvsc_drv.c
+++ b/drivers/staging/hv/storvsc_drv.c
@@ -1380,7 +1380,8 @@ MODULE_DEVICE_TABLE(vmbus, id_table);
  * storvsc_probe - Add a new device for this driver
  */
 
-static int storvsc_probe(struct hv_device *device)
+static int storvsc_probe(struct hv_device *device,
+			const struct hv_vmbus_device_id *dev_id)
 {
 	int ret;
 	struct Scsi_Host *host;
diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c
index 375e451..c7df7f4 100644
--- a/drivers/staging/hv/vmbus_drv.c
+++ b/drivers/staging/hv/vmbus_drv.c
@@ -299,9 +299,15 @@ static int vmbus_probe(struct device *child_device)
 	struct hv_driver *drv =
 			drv_to_hv_drv(child_device->driver);
 	struct hv_device *dev = device_to_hv_device(child_device);
+	const struct hv_vmbus_device_id *dev_id = drv->id_table;
+
+	for (; !is_null_guid(dev_id->guid); dev_id++)
+		if (!memcmp(&dev_id->guid, &dev->dev_type.b,
+				sizeof(uuid_le)))
+			break;
 
 	if (drv->probe) {
-		ret = drv->probe(dev);
+		ret = drv->probe(dev, dev_id);
 		if (ret != 0)
 			pr_err("probe failed for device %s (%d)\n",
 			       dev_name(child_device), ret);
-- 
1.7.4.1

^ permalink raw reply related

* [PATCH 06/25] Staging: hv: storvsc: Use the driver_data to identify ide
From: K. Y. Srinivasan @ 2011-09-08 14:24 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, virtualization; +Cc: Haiyang Zhang
In-Reply-To: <1315491876-9554-1-git-send-email-kys@microsoft.com>

Use the driver_data to identify ide devices in storvsc_probe().

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 drivers/staging/hv/storvsc_drv.c |   13 +++++--------
 1 files changed, 5 insertions(+), 8 deletions(-)

diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c
index fff1e5b..e2c63e5 100644
--- a/drivers/staging/hv/storvsc_drv.c
+++ b/drivers/staging/hv/storvsc_drv.c
@@ -1366,10 +1366,12 @@ static struct scsi_host_template scsi_driver = {
 static const struct hv_vmbus_device_id id_table[] = {
 	/* SCSI guid */
 	{ VMBUS_DEVICE(0xd9, 0x63, 0x61, 0xba, 0xa1, 0x04, 0x29, 0x4d,
-		       0xb6, 0x05, 0x72, 0xe2, 0xff, 0xb1, 0xdc, 0x7f) },
+		       0xb6, 0x05, 0x72, 0xe2, 0xff, 0xb1, 0xdc, 0x7f)
+	  .driver_data = 0 },
 	/* IDE guid */
 	{ VMBUS_DEVICE(0x32, 0x26, 0x41, 0x32, 0xcb, 0x86, 0xa2, 0x44,
-		       0x9b, 0x5c, 0x50, 0xd1, 0x41, 0x73, 0x54, 0xf5) },
+		       0x9b, 0x5c, 0x50, 0xd1, 0x41, 0x73, 0x54, 0xf5)
+	  .driver_data = 1 },
 	{ },
 };
 
@@ -1387,15 +1389,10 @@ static int storvsc_probe(struct hv_device *device,
 	struct Scsi_Host *host;
 	struct hv_host_device *host_dev;
 	struct storvsc_device_info device_info;
-	bool dev_is_ide;
+	bool dev_is_ide = ((dev_id->driver_data == 1) ? true : false);
 	int path = 0;
 	int target = 0;
 
-	if (!memcmp(&device->dev_type.b, id_table[1].guid, sizeof(uuid_le)))
-		dev_is_ide = true;
-	else
-		dev_is_ide = false;
-
 	host = scsi_host_alloc(&scsi_driver,
 			       sizeof(struct hv_host_device));
 	if (!host)
-- 
1.7.4.1

^ permalink raw reply related

* [PATCH 07/25] Staging: hv: vmbus: Change the signature of struct hv_driver remove() function
From: K. Y. Srinivasan @ 2011-09-08 14:24 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, virtualization; +Cc: Haiyang Zhang
In-Reply-To: <1315491876-9554-1-git-send-email-kys@microsoft.com>

In preparation for leveraging the driver_data in  struct
hv_vmbus_device_id, change the signature of struct hv_driver remove() function.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 drivers/staging/hv/hv_mouse.c    |    3 ++-
 drivers/staging/hv/hv_util.c     |    3 ++-
 drivers/staging/hv/hyperv.h      |    2 +-
 drivers/staging/hv/netvsc_drv.c  |    3 ++-
 drivers/staging/hv/storvsc_drv.c |    3 ++-
 drivers/staging/hv/vmbus_drv.c   |    9 ++++++++-
 6 files changed, 17 insertions(+), 6 deletions(-)

diff --git a/drivers/staging/hv/hv_mouse.c b/drivers/staging/hv/hv_mouse.c
index 5ff8a03..d60f287 100644
--- a/drivers/staging/hv/hv_mouse.c
+++ b/drivers/staging/hv/hv_mouse.c
@@ -847,7 +847,8 @@ static int mousevsc_probe(struct hv_device *dev,
 	return 0;
 }
 
-static int mousevsc_remove(struct hv_device *dev)
+static int mousevsc_remove(struct hv_device *dev,
+				const struct hv_vmbus_device_id *dev_id)
 {
 	struct input_device_context *input_dev_ctx;
 	int ret;
diff --git a/drivers/staging/hv/hv_util.c b/drivers/staging/hv/hv_util.c
index d9460fdd..661631d 100644
--- a/drivers/staging/hv/hv_util.c
+++ b/drivers/staging/hv/hv_util.c
@@ -245,7 +245,8 @@ static int util_probe(struct hv_device *dev,
 	return 0;
 }
 
-static int util_remove(struct hv_device *dev)
+static int util_remove(struct hv_device *dev,
+			const struct hv_vmbus_device_id *dev_id)
 {
 	return 0;
 }
diff --git a/drivers/staging/hv/hyperv.h b/drivers/staging/hv/hyperv.h
index caa3a7b..cf02ae1 100644
--- a/drivers/staging/hv/hyperv.h
+++ b/drivers/staging/hv/hyperv.h
@@ -811,7 +811,7 @@ struct hv_driver {
 	struct device_driver driver;
 
 	int (*probe)(struct hv_device *, const struct hv_vmbus_device_id *);
-	int (*remove)(struct hv_device *);
+	int (*remove)(struct hv_device *, const struct hv_vmbus_device_id *);
 	void (*shutdown)(struct hv_device *);
 
 };
diff --git a/drivers/staging/hv/netvsc_drv.c b/drivers/staging/hv/netvsc_drv.c
index d06cde2..d0189a3 100644
--- a/drivers/staging/hv/netvsc_drv.c
+++ b/drivers/staging/hv/netvsc_drv.c
@@ -384,7 +384,8 @@ out:
 	return ret;
 }
 
-static int netvsc_remove(struct hv_device *dev)
+static int netvsc_remove(struct hv_device *dev,
+			const struct hv_vmbus_device_id *dev_id)
 {
 	struct net_device *net = dev_get_drvdata(&dev->device);
 	struct net_device_context *ndev_ctx;
diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c
index e2c63e5..e5da758 100644
--- a/drivers/staging/hv/storvsc_drv.c
+++ b/drivers/staging/hv/storvsc_drv.c
@@ -1021,7 +1021,8 @@ static unsigned int copy_to_bounce_buffer(struct scatterlist *orig_sgl,
 }
 
 
-static int storvsc_remove(struct hv_device *dev)
+static int storvsc_remove(struct hv_device *dev,
+				const struct hv_vmbus_device_id *dev_id)
 {
 	struct Scsi_Host *host = dev_get_drvdata(&dev->device);
 	struct hv_host_device *host_dev =
diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c
index c7df7f4..b9aeb76 100644
--- a/drivers/staging/hv/vmbus_drv.c
+++ b/drivers/staging/hv/vmbus_drv.c
@@ -329,12 +329,19 @@ static int vmbus_remove(struct device *child_device)
 	struct hv_driver *drv;
 
 	struct hv_device *dev = device_to_hv_device(child_device);
+	const struct hv_vmbus_device_id *dev_id;
 
 	if (child_device->driver) {
 		drv = drv_to_hv_drv(child_device->driver);
+		dev_id = drv->id_table;
+
+		for (; !is_null_guid(dev_id->guid); dev_id++)
+			if (!memcmp(&dev_id->guid, &dev->dev_type.b,
+					sizeof(uuid_le)))
+				break;
 
 		if (drv->remove) {
-			ret = drv->remove(dev);
+			ret = drv->remove(dev, dev_id);
 		} else {
 			pr_err("remove not set for driver %s\n",
 				dev_name(child_device));
-- 
1.7.4.1

^ permalink raw reply related

* [PATCH 08/25] Staging: hv: util: Perform some service specific initialization in util_probe()
From: K. Y. Srinivasan @ 2011-09-08 14:24 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, virtualization; +Cc: Haiyang Zhang
In-Reply-To: <1315491876-9554-1-git-send-email-kys@microsoft.com>

In preparation for modifying the util driver to fully conform to the 
Linux Driver Model, perform some service specific initialization in
util_probe() as opposed to in init_hyperv_utils() as is currently done. 

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 drivers/staging/hv/hv_util.c |   77 ++++++++++++++++++++++++++++-------------
 1 files changed, 52 insertions(+), 25 deletions(-)

diff --git a/drivers/staging/hv/hv_util.c b/drivers/staging/hv/hv_util.c
index 661631d..b86128a 100644
--- a/drivers/staging/hv/hv_util.c
+++ b/drivers/staging/hv/hv_util.c
@@ -34,6 +34,13 @@ static u8 *shut_txf_buf;
 static u8 *time_txf_buf;
 static u8 *hbeat_txf_buf;
 
+enum hv_util_services {
+	HV_SHUTDOWN,
+	HV_TIMESYNC,
+	HV_HEARTBEAT,
+	HV_KVP,
+};
+
 static void shutdown_onchannelcallback(void *context)
 {
 	struct vmbus_channel *channel = context;
@@ -242,7 +249,43 @@ static void heartbeat_onchannelcallback(void *context)
 static int util_probe(struct hv_device *dev,
 			const struct hv_vmbus_device_id *dev_id)
 {
+	void *buf = NULL;
+	int service = dev_id->driver_data;
+
+	switch (service) {
+	case HV_SHUTDOWN:
+		buf = shut_txf_buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
+		if (!shut_txf_buf)
+			goto error;
+		break;
+
+	case HV_TIMESYNC:
+		buf = time_txf_buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
+		if (!time_txf_buf)
+			goto error;
+		break;
+
+	case HV_HEARTBEAT:
+		buf = hbeat_txf_buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
+		if (!hbeat_txf_buf)
+			goto error;
+		break;
+
+	case HV_KVP:
+		if (hv_kvp_init())
+			return -ENODEV;
+		break;
+
+	default:
+		pr_err("unknown util service\n");
+		return -ENODEV;
+	}
+
 	return 0;
+
+error:
+	return -ENOMEM;
+
 }
 
 static int util_remove(struct hv_device *dev,
@@ -254,16 +297,20 @@ static int util_remove(struct hv_device *dev,
 static const struct hv_vmbus_device_id id_table[] = {
 	/* Shutdown guid */
 	{ VMBUS_DEVICE(0x31, 0x60, 0x0B, 0X0E, 0x13, 0x52, 0x34, 0x49,
-		       0x81, 0x8B, 0x38, 0XD9, 0x0C, 0xED, 0x39, 0xDB) },
+		       0x81, 0x8B, 0x38, 0XD9, 0x0C, 0xED, 0x39, 0xDB)
+	  .driver_data = HV_SHUTDOWN },
 	/* Time synch guid */
 	{ VMBUS_DEVICE(0x30, 0xe6, 0x27, 0x95, 0xae, 0xd0, 0x7b, 0x49,
-		       0xad, 0xce, 0xe8, 0x0a, 0xb0, 0x17, 0x5c, 0xaf) },
+		       0xad, 0xce, 0xe8, 0x0a, 0xb0, 0x17, 0x5c, 0xaf)
+	  .driver_data = HV_TIMESYNC },
 	/* Heartbeat guid */
 	{ VMBUS_DEVICE(0x39, 0x4f, 0x16, 0x57, 0x15, 0x91, 0x78, 0x4e,
-		       0xab, 0x55, 0x38, 0x2f, 0x3b, 0xd5, 0x42, 0x2d) },
+		       0xab, 0x55, 0x38, 0x2f, 0x3b, 0xd5, 0x42, 0x2d)
+	  .driver_data = HV_HEARTBEAT },
 	/* KVP guid */
 	{ VMBUS_DEVICE(0xe7, 0xf4, 0xa0, 0xa9, 0x45, 0x5a, 0x96, 0x4d,
-		       0xb8, 0x27, 0x8a, 0x84, 0x1e, 0x8c, 0x3,  0xe6) },
+		       0xb8, 0x27, 0x8a, 0x84, 0x1e, 0x8c, 0x3,  0xe6)
+	  .driver_data = HV_KVP },
 	{ },
 };
 
@@ -282,24 +329,10 @@ static int __init init_hyperv_utils(void)
 	int ret;
 	pr_info("Registering HyperV Utility Driver\n");
 
-	if (hv_kvp_init())
-		return -ENODEV;
-
-
-	shut_txf_buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
-	time_txf_buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
-	hbeat_txf_buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
-
-	if (!shut_txf_buf || !time_txf_buf || !hbeat_txf_buf) {
-		pr_info("Unable to allocate memory for receive buffer\n");
-		ret = -ENOMEM;
-		goto err;
-	}
-
 	ret = vmbus_driver_register(&util_drv);
 
 	if (ret != 0)
-		goto err;
+		return ret;
 
 	hv_cb_utils[HV_SHUTDOWN_MSG].callback = &shutdown_onchannelcallback;
 
@@ -311,12 +344,6 @@ static int __init init_hyperv_utils(void)
 
 	return 0;
 
-err:
-	kfree(shut_txf_buf);
-	kfree(time_txf_buf);
-	kfree(hbeat_txf_buf);
-
-	return ret;
 }
 
 static void exit_hyperv_utils(void)
-- 
1.7.4.1

^ permalink raw reply related

* [PATCH 09/25] Staging: hv: util: Perform some service specific de-initialization in util_remove()
From: K. Y. Srinivasan @ 2011-09-08 14:24 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, virtualization; +Cc: Haiyang Zhang
In-Reply-To: <1315491876-9554-1-git-send-email-kys@microsoft.com>

In preparation for modifying the util driver to fully conform to the
Linux Driver Model, perform some service specific de-initialization in
util_remove() as opposed to in exit_hyperv_utils() as is currently done.


Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 drivers/staging/hv/hv_util.c |   29 ++++++++++++++++++++++++-----
 1 files changed, 24 insertions(+), 5 deletions(-)

diff --git a/drivers/staging/hv/hv_util.c b/drivers/staging/hv/hv_util.c
index b86128a..2475ab2 100644
--- a/drivers/staging/hv/hv_util.c
+++ b/drivers/staging/hv/hv_util.c
@@ -291,6 +291,30 @@ error:
 static int util_remove(struct hv_device *dev,
 			const struct hv_vmbus_device_id *dev_id)
 {
+	int service = dev_id->driver_data;
+
+	switch (service) {
+	case HV_SHUTDOWN:
+		kfree(shut_txf_buf);
+		break;
+
+	case HV_TIMESYNC:
+		kfree(time_txf_buf);
+		break;
+
+	case HV_HEARTBEAT:
+		kfree(hbeat_txf_buf);
+		break;
+
+	case HV_KVP:
+		hv_kvp_deinit();
+		break;
+
+	default:
+		pr_err("unknown util service\n");
+		return -ENODEV;
+	}
+
 	return 0;
 }
 
@@ -370,11 +394,6 @@ static void exit_hyperv_utils(void)
 			&chn_cb_negotiate;
 	hv_cb_utils[HV_KVP_MSG].callback = NULL;
 
-	hv_kvp_deinit();
-
-	kfree(shut_txf_buf);
-	kfree(time_txf_buf);
-	kfree(hbeat_txf_buf);
 	vmbus_driver_unregister(&util_drv);
 }
 
-- 
1.7.4.1

^ permalink raw reply related

* [PATCH 10/25] Staging: hv: vmbus: Return proper error code in vmbus_remove()
From: K. Y. Srinivasan @ 2011-09-08 14:24 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, virtualization
  Cc: K. Y. Srinivasan, Haiyang Zhang
In-Reply-To: <1315491876-9554-1-git-send-email-kys@microsoft.com>

Return proper error code in vmbus_remove().

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 drivers/staging/hv/vmbus_drv.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c
index b9aeb76..95d33a4 100644
--- a/drivers/staging/hv/vmbus_drv.c
+++ b/drivers/staging/hv/vmbus_drv.c
@@ -325,7 +325,7 @@ static int vmbus_probe(struct device *child_device)
  */
 static int vmbus_remove(struct device *child_device)
 {
-	int ret;
+	int ret = 0;
 	struct hv_driver *drv;
 
 	struct hv_device *dev = device_to_hv_device(child_device);
@@ -349,7 +349,7 @@ static int vmbus_remove(struct device *child_device)
 		}
 	}
 
-	return 0;
+	return ret;
 }
 
 
-- 
1.7.4.1

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox