[PATCH v2] staging: iio: ad7606: use iio_device_{claim|release}_direct_mode()

2016-04-05 Thread Alison Schofield
Replace the code that guarantees the device stays in direct mode with
iio_device_{claim|release}_direct_mode() which does same.

Signed-off-by: Alison Schofield 
---
Changed in v2:
 - removed improper application of claim/release from intr handler
 - updated changelog

 drivers/staging/iio/adc/ad7606_core.c | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/staging/iio/adc/ad7606_core.c 
b/drivers/staging/iio/adc/ad7606_core.c
index 6dbc811..f79ee61 100644
--- a/drivers/staging/iio/adc/ad7606_core.c
+++ b/drivers/staging/iio/adc/ad7606_core.c
@@ -88,12 +88,12 @@ static int ad7606_read_raw(struct iio_dev *indio_dev,
 
switch (m) {
case IIO_CHAN_INFO_RAW:
-   mutex_lock(&indio_dev->mlock);
-   if (iio_buffer_enabled(indio_dev))
-   ret = -EBUSY;
-   else
-   ret = ad7606_scan_direct(indio_dev, chan->address);
-   mutex_unlock(&indio_dev->mlock);
+   ret = iio_device_claim_direct_mode(indio_dev);
+   if (ret)
+   return ret;
+
+   ret = ad7606_scan_direct(indio_dev, chan->address);
+   iio_device_release_direct_mode(indio_dev);
 
if (ret < 0)
return ret;
-- 
2.1.4

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


RE: [PATCH] staging: comedi: das1800: remove unused variable

2016-04-05 Thread Hartley Sweeten
On Tuesday, April 05, 2016 7:23 AM, Sudip Mukherjee wrote:
> The variable unipolar was never used.
>
> Signed-off-by: Sudip Mukherjee 
> ---
>
> There may be a chance that reading from DAS1800_CONTROL_C is necessary
> before reading from DAS1800_STATUS. If that is true then please discard
> this patch.

Actually the driver has a bug here.

The analog input samples should  be munged if the inputs are configured for
bipolar mode.

I have a series almost ready that cleans up this driver and fixes the bug.

Thanks,
Hartley

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v5 6/6] drivers:hv: Separate out frame buffer logic when picking MMIO range

2016-04-05 Thread Jake Oshins
Simplify the logic that picks MMIO ranges by pulling out the
logic related to trying to lay frame buffer claim on top of where
the firmware placed the frame buffer.

Signed-off-by: Jake Oshins 
---
 drivers/hv/vmbus_drv.c | 80 ++
 1 file changed, 35 insertions(+), 45 deletions(-)

diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index eaa5c3b..a29a6c0 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -1162,64 +1162,54 @@ int vmbus_allocate_mmio(struct resource **new, struct 
hv_device *device_obj,
bool fb_overlap_ok)
 {
struct resource *iter, *shadow;
-   resource_size_t range_min, range_max, start, local_min, local_max;
+   resource_size_t range_min, range_max, start;
const char *dev_n = dev_name(&device_obj->device);
-   u32 fb_end = screen_info.lfb_base + (screen_info.lfb_size << 1);
-   int i, retval;
+   int retval;
 
retval = -ENXIO;
down(&hyperv_mmio_lock);
 
+   /*
+* If overlaps with frame buffers are allowed, then first attempt to
+* make the allocation from within the reserved region.  Because it
+* is already reserved, no shadow allocation is necessary.
+*/
+   if (fb_overlap_ok && fb_mmio && !(min > fb_mmio->end) &&
+   !(max < fb_mmio->start)) {
+
+   range_min = fb_mmio->start;
+   range_max = fb_mmio->end;
+   start = (range_min + align - 1) & ~(align - 1);
+   for (; start + size - 1 <= range_max; start += align) {
+   *new = request_mem_region_exclusive(start, size, dev_n);
+   if (*new) {
+   retval = 0;
+   goto exit;
+   }
+   }
+   }
+
for (iter = hyperv_mmio; iter; iter = iter->sibling) {
if ((iter->start >= max) || (iter->end <= min))
continue;
 
range_min = iter->start;
range_max = iter->end;
-
-   /* If this range overlaps the frame buffer, split it into
-  two tries. */
-   for (i = 0; i < 2; i++) {
-   local_min = range_min;
-   local_max = range_max;
-   if (fb_overlap_ok || (range_min >= fb_end) ||
-   (range_max <= screen_info.lfb_base)) {
-   i++;
-   } else {
-   if ((range_min <= screen_info.lfb_base) &&
-   (range_max >= screen_info.lfb_base)) {
-   /*
-* The frame buffer is in this window,
-* so trim this into the part that
-* preceeds the frame buffer.
-*/
-   local_max = screen_info.lfb_base - 1;
-   range_min = fb_end;
-   } else {
-   range_min = fb_end;
-   continue;
-   }
+   start = (range_min + align - 1) & ~(align - 1);
+   for (; start + size - 1 <= range_max; start += align) {
+   shadow = __request_region(iter, start, size, NULL,
+ IORESOURCE_BUSY);
+   if (!shadow)
+   continue;
+
+   *new = request_mem_region_exclusive(start, size, dev_n);
+   if (*new) {
+   shadow->name = (char *)*new;
+   retval = 0;
+   goto exit;
}
 
-   start = (local_min + align - 1) & ~(align - 1);
-   for (; start + size - 1 <= local_max; start += align) {
-   shadow = __request_region(iter, start,
- size,
- NULL,
- IORESOURCE_BUSY);
-   if (!shadow)
-   continue;
-
-   *new = request_mem_region_exclusive(start, size,
-   dev_n);
-   if (*new) {
-   shadow->name = (char *)*new;
-   retval = 0;
-   goto exit;
-   }
-
-   __release_region(iter, start, size);
-

[PATCH v5 2/6] drivers:hv: Call vmbus_mmio_free() to reverse vmbus_mmio_allocate()

2016-04-05 Thread Jake Oshins
Existing code just called release_mem_region().  Adding a
wrapper around it allows the more complex range tracking
that is introduced later in this patch series.

Signed-off-by: Jake Oshins 
---
 drivers/hv/vmbus_drv.c  | 15 +++
 drivers/pci/host/pci-hyperv.c   | 14 +++---
 drivers/video/fbdev/hyperv_fb.c |  4 ++--
 include/linux/hyperv.h  |  2 +-
 4 files changed, 25 insertions(+), 10 deletions(-)

diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index 799518b..60553c1 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -1188,6 +1188,21 @@ exit:
 EXPORT_SYMBOL_GPL(vmbus_allocate_mmio);
 
 /**
+ * vmbus_free_mmio() - Free a memory-mapped I/O range.
+ * @start: Base address of region to release.
+ * @size:  Size of the range to be allocated
+ *
+ * This function releases anything requested by
+ * vmbus_mmio_allocate().
+ */
+void vmbus_free_mmio(resource_size_t start, resource_size_t size)
+{
+   release_mem_region(start, size);
+
+}
+EXPORT_SYMBOL_GPL(vmbus_free_mmio);
+
+/**
  * vmbus_cpu_number_to_vp_number() - Map CPU to VP.
  * @cpu_number: CPU number in Linux terms
  *
diff --git a/drivers/pci/host/pci-hyperv.c b/drivers/pci/host/pci-hyperv.c
index ed651ba..f2559b6 100644
--- a/drivers/pci/host/pci-hyperv.c
+++ b/drivers/pci/host/pci-hyperv.c
@@ -1795,14 +1795,14 @@ static void hv_pci_free_bridge_windows(struct 
hv_pcibus_device *hbus)
 
if (hbus->low_mmio_space && hbus->low_mmio_res) {
hbus->low_mmio_res->flags |= IORESOURCE_BUSY;
-   release_mem_region(hbus->low_mmio_res->start,
-  resource_size(hbus->low_mmio_res));
+   vmbus_free_mmio(hbus->low_mmio_res->start,
+   resource_size(hbus->low_mmio_res));
}
 
if (hbus->high_mmio_space && hbus->high_mmio_res) {
hbus->high_mmio_res->flags |= IORESOURCE_BUSY;
-   release_mem_region(hbus->high_mmio_res->start,
-  resource_size(hbus->high_mmio_res));
+   vmbus_free_mmio(hbus->high_mmio_res->start,
+   resource_size(hbus->high_mmio_res));
}
 }
 
@@ -1880,8 +1880,8 @@ static int hv_pci_allocate_bridge_windows(struct 
hv_pcibus_device *hbus)
 
 release_low_mmio:
if (hbus->low_mmio_res) {
-   release_mem_region(hbus->low_mmio_res->start,
-  resource_size(hbus->low_mmio_res));
+   vmbus_free_mmio(hbus->low_mmio_res->start,
+   resource_size(hbus->low_mmio_res));
}
 
return ret;
@@ -1924,7 +1924,7 @@ static int hv_allocate_config_window(struct 
hv_pcibus_device *hbus)
 
 static void hv_free_config_window(struct hv_pcibus_device *hbus)
 {
-   release_mem_region(hbus->mem_config->start, PCI_CONFIG_MMIO_LENGTH);
+   vmbus_free_mmio(hbus->mem_config->start, PCI_CONFIG_MMIO_LENGTH);
 }
 
 /**
diff --git a/drivers/video/fbdev/hyperv_fb.c b/drivers/video/fbdev/hyperv_fb.c
index e2451bd..2fd49b2 100644
--- a/drivers/video/fbdev/hyperv_fb.c
+++ b/drivers/video/fbdev/hyperv_fb.c
@@ -743,7 +743,7 @@ static int hvfb_getmem(struct hv_device *hdev, struct 
fb_info *info)
 err3:
iounmap(fb_virt);
 err2:
-   release_mem_region(par->mem->start, screen_fb_size);
+   vmbus_free_mmio(par->mem->start, screen_fb_size);
par->mem = NULL;
 err1:
if (!gen2vm)
@@ -758,7 +758,7 @@ static void hvfb_putmem(struct fb_info *info)
struct hvfb_par *par = info->par;
 
iounmap(info->screen_base);
-   release_mem_region(par->mem->start, screen_fb_size);
+   vmbus_free_mmio(par->mem->start, screen_fb_size);
par->mem = NULL;
 }
 
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index aa0fadc..ecd81c3 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -1091,7 +1091,7 @@ int vmbus_allocate_mmio(struct resource **new, struct 
hv_device *device_obj,
resource_size_t min, resource_size_t max,
resource_size_t size, resource_size_t align,
bool fb_overlap_ok);
-
+void vmbus_free_mmio(resource_size_t start, resource_size_t size);
 int vmbus_cpu_number_to_vp_number(int cpu_number);
 u64 hv_do_hypercall(u64 control, void *input, void *output);
 
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v5 5/6] drivers:hv: Record MMIO range in use by frame buffer

2016-04-05 Thread Jake Oshins
Later in the boot sequence, we need to figure out which memory
ranges can be given out to various paravirtual drivers.  The
hyperv_fb driver should, ideally, be placed right on top of
the frame buffer, without some other device getting plopped on
top of this range in the meantime.  Recording this now allows
that to be guaranteed.

Signed-off-by: Jake Oshins 
---
 drivers/hv/vmbus_drv.c | 37 -
 1 file changed, 36 insertions(+), 1 deletion(-)

diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index dfc6149..eaa5c3b 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -41,6 +41,7 @@
 #include 
 #include 
 #include 
+#include 
 #include "hyperv_vmbus.h"
 
 static struct acpi_device  *hv_acpi_dev;
@@ -101,6 +102,8 @@ static struct notifier_block hyperv_panic_block = {
.notifier_call = hyperv_panic_event,
 };
 
+static const char *fb_mmio_name = "fb_range";
+static struct resource *fb_mmio;
 struct resource *hyperv_mmio;
 DEFINE_SEMAPHORE(hyperv_mmio_lock);
 
@@ -1091,6 +1094,12 @@ static int vmbus_acpi_remove(struct acpi_device *device)
struct resource *next_res;
 
if (hyperv_mmio) {
+   if (fb_mmio) {
+   __release_region(hyperv_mmio, fb_mmio->start,
+resource_size(fb_mmio));
+   fb_mmio = NULL;
+   }
+
for (cur_res = hyperv_mmio; cur_res; cur_res = next_res) {
next_res = cur_res->sibling;
kfree(cur_res);
@@ -1100,6 +1109,30 @@ static int vmbus_acpi_remove(struct acpi_device *device)
return 0;
 }
 
+static void vmbus_reserve_fb(void)
+{
+   int size;
+   /*
+* Make a claim for the frame buffer in the resource tree under the
+* first node, which will be the one below 4GB.  The length seems to
+* be underreported, particularly in a Generation 1 VM.  So start out
+* reserving a larger area and make it smaller until it succeeds.
+*/
+
+   if (screen_info.lfb_base) {
+   if (efi_enabled(EFI_BOOT))
+   size = max_t(__u32, screen_info.lfb_size, 0x80);
+   else
+   size = max_t(__u32, screen_info.lfb_size, 0x400);
+
+   for (; !fb_mmio && (size >= 0x10); size >>= 1) {
+   fb_mmio = __request_region(hyperv_mmio,
+  screen_info.lfb_base, size,
+  fb_mmio_name, 0);
+   }
+   }
+}
+
 /**
  * vmbus_allocate_mmio() - Pick a memory-mapped I/O range.
  * @new:   If successful, supplied a pointer to the
@@ -1261,8 +1294,10 @@ static int vmbus_acpi_add(struct acpi_device *device)
 
if (ACPI_FAILURE(result))
continue;
-   if (hyperv_mmio)
+   if (hyperv_mmio) {
+   vmbus_reserve_fb();
break;
+   }
}
ret_val = 0;
 
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v5 4/6] drivers:hv: Track allocations of children of hv_vmbus in private resource tree

2016-04-05 Thread Jake Oshins
This patch changes vmbus_allocate_mmio() and vmbus_free_mmio() so
that when child paravirtual devices allocate memory-mapped I/O
space, they allocate it privately from a resource tree pointed
at by hyperv_mmio and also by the public resource tree
iomem_resource.  This allows the region to be marked as "busy"
in the private tree, but a "bridge window" in the public tree,
guaranteeing that no two bridge windows will overlap each other
but while also allowing the PCI device children of the bridge
windows to overlap that window.

One might conclude that this belongs in the pnp layer, rather
than in this driver.  Rafael Wysocki, the maintainter of the
pnp layer, has previously asked that we not modify the pnp layer
as it is considered deprecated.  This patch is thus essentially
a workaround.

Signed-off-by: Jake Oshins 
---
 drivers/hv/vmbus_drv.c | 22 +-
 1 file changed, 21 insertions(+), 1 deletion(-)

diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index 1ce47d0..dfc6149 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -1128,7 +1128,7 @@ int vmbus_allocate_mmio(struct resource **new, struct 
hv_device *device_obj,
resource_size_t size, resource_size_t align,
bool fb_overlap_ok)
 {
-   struct resource *iter;
+   struct resource *iter, *shadow;
resource_size_t range_min, range_max, start, local_min, local_max;
const char *dev_n = dev_name(&device_obj->device);
u32 fb_end = screen_info.lfb_base + (screen_info.lfb_size << 1);
@@ -1170,12 +1170,22 @@ int vmbus_allocate_mmio(struct resource **new, struct 
hv_device *device_obj,
 
start = (local_min + align - 1) & ~(align - 1);
for (; start + size - 1 <= local_max; start += align) {
+   shadow = __request_region(iter, start,
+ size,
+ NULL,
+ IORESOURCE_BUSY);
+   if (!shadow)
+   continue;
+
*new = request_mem_region_exclusive(start, size,
dev_n);
if (*new) {
+   shadow->name = (char *)*new;
retval = 0;
goto exit;
}
+
+   __release_region(iter, start, size);
}
}
}
@@ -1196,7 +1206,17 @@ EXPORT_SYMBOL_GPL(vmbus_allocate_mmio);
  */
 void vmbus_free_mmio(resource_size_t start, resource_size_t size)
 {
+   struct resource *iter;
+
+   down(&hyperv_mmio_lock);
+   for (iter = hyperv_mmio; iter; iter = iter->sibling) {
+   if ((iter->start >= start + size) || (iter->end <= start))
+   continue;
+
+   __release_region(iter, start, size);
+   }
release_mem_region(start, size);
+   up(&hyperv_mmio_lock);
 
 }
 EXPORT_SYMBOL_GPL(vmbus_free_mmio);
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v5 1/6] drivers:hv: Lock access to hyperv_mmio resource tree

2016-04-05 Thread Jake Oshins
In existing code, this tree of resources is created
in single-threaded code and never modified after it is
created, and thus needs no locking.  This patch introduces
a semaphore for tree access, as other patches in this
series introduce run-time modifications of this resource
tree which can happen on multiple threads.

Signed-off-by: Jake Oshins 
---
 drivers/hv/vmbus_drv.c | 16 
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index 64713ff..799518b 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -102,6 +102,7 @@ static struct notifier_block hyperv_panic_block = {
 };
 
 struct resource *hyperv_mmio;
+DEFINE_SEMAPHORE(hyperv_mmio_lock);
 
 static int vmbus_exists(void)
 {
@@ -1132,7 +1133,10 @@ int vmbus_allocate_mmio(struct resource **new, struct 
hv_device *device_obj,
resource_size_t range_min, range_max, start, local_min, local_max;
const char *dev_n = dev_name(&device_obj->device);
u32 fb_end = screen_info.lfb_base + (screen_info.lfb_size << 1);
-   int i;
+   int i, retval;
+
+   retval = -ENXIO;
+   down(&hyperv_mmio_lock);
 
for (iter = hyperv_mmio; iter; iter = iter->sibling) {
if ((iter->start >= max) || (iter->end <= min))
@@ -1169,13 +1173,17 @@ int vmbus_allocate_mmio(struct resource **new, struct 
hv_device *device_obj,
for (; start + size - 1 <= local_max; start += align) {
*new = request_mem_region_exclusive(start, size,
dev_n);
-   if (*new)
-   return 0;
+   if (*new) {
+   retval = 0;
+   goto exit;
+   }
}
}
}
 
-   return -ENXIO;
+exit:
+   up(&hyperv_mmio_lock);
+   return retval;
 }
 EXPORT_SYMBOL_GPL(vmbus_allocate_mmio);
 
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v5 3/6] drivers:hv: Reverse order of resources in hyperv_mmio

2016-04-05 Thread Jake Oshins
A patch later in this series allocates child nodes
in this resource tree.  For that to work, this tree
needs to be sorted in ascending order.

Signed-off-by: Jake Oshins 
---
 drivers/hv/vmbus_drv.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index 60553c1..1ce47d0 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -1049,7 +1049,6 @@ static acpi_status vmbus_walk_resources(struct 
acpi_resource *res, void *ctx)
new_res->end = end;
 
/*
-* Stick ranges from higher in address space at the front of the list.
 * If two ranges are adjacent, merge them.
 */
do {
@@ -1070,7 +1069,7 @@ static acpi_status vmbus_walk_resources(struct 
acpi_resource *res, void *ctx)
break;
}
 
-   if ((*old_res)->end < new_res->start) {
+   if ((*old_res)->start > new_res->end) {
new_res->sibling = *old_res;
if (prev_res)
(*prev_res)->sibling = new_res;
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v5 0/6] drivers:hv: Ensure that bridge windows don't overlap

2016-04-05 Thread Jake Oshins
This version incorporates feedback from Bjorn Helgaas, folding two
patches together.

Hyper-V VMs expose paravirtual drivers through a mechanism called
VMBus, which is managed by hv_vmbus.ko.  For each parvirtual service
instance, this driver exposes a new child device.  Some of these child
devices need memory address space, into which Hyper-V will map things
like the virtual video frame buffer.  This memory-mapped address space
is chosen by the guest OS, not the hypervisor.

This is difficult to map onto the Linux pnp layer, as the code in the
pnp layer to choose MMIO space keys off of bus type and it doesn't know
anything about VMBus.  The maintainers of the pnp layer have asked that
we not offer patches to it that make it understand VMBus, but that we
rather find ways of using the code in its current state.  So hv_vmbus.ko
exports a function, vmbus_allocate_mmio() for choosing the address space
for any child driver that needs this facility.

The recently introduced PCI front-end driver for Hyper-V VMs
(pci-hyperv.ko) uses vmbus_allocate_mmio() for choosing both the region
of memory space into which real PCI Express devices are mapped.  The
regions allocated are made to look like root PCI bus bridge windows
to the PCI driver, reusing all the code in the PCI driver for the rest
of PCI device management.

The problem is that these bridge windows are marked in such a way that
devices can still allocate from the memory space spanned by them, and
this means that if two different PCI buses are created in the VM, each
with devices under them, they may allocate the same memory space, leading
to PCI Base Address Register which overlap.

This patch series fixes the problem by tracking allocations to child
devices in a separate resource tree, marking them such that the bridge
windows can't overlap.  The main memory resource tree, iomem_resource,
contains resources properly marked as bridge windows, allowing their
children to overlap with them.

Jake Oshins (6):
  drivers:hv: Lock access to hyperv_mmio resource tree
  drivers:hv: Call vmbus_mmio_free() to reverse vmbus_mmio_allocate()
  drivers:hv: Reverse order of resources in hyperv_mmio
  drivers:hv: Track allocations of children of hv_vmbus in private
resource tree
  drivers:hv: Record MMIO range in use by frame buffer
  drivers:hv: Separate out frame buffer logic when picking MMIO range

 drivers/hv/vmbus_drv.c  | 143 +---
 drivers/pci/host/pci-hyperv.c   |  14 ++--
 drivers/video/fbdev/hyperv_fb.c |   4 +-
 include/linux/hyperv.h  |   2 +-
 4 files changed, 115 insertions(+), 48 deletions(-)

--
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 2/8] Drivers: hv: vmbus: Introduce functions for estimating room in the ring buffer

2016-04-05 Thread K. Y. Srinivasan
Introduce separate functions for estimating how much can be read from
and written to the ring buffer.

Signed-off-by: K. Y. Srinivasan 
---
 drivers/hv/ring_buffer.c |   25 -
 include/linux/hyperv.h   |   27 +++
 2 files changed, 31 insertions(+), 21 deletions(-)

diff --git a/drivers/hv/ring_buffer.c b/drivers/hv/ring_buffer.c
index a40a73a..544362c 100644
--- a/drivers/hv/ring_buffer.c
+++ b/drivers/hv/ring_buffer.c
@@ -38,8 +38,6 @@ void hv_begin_read(struct hv_ring_buffer_info *rbi)
 
 u32 hv_end_read(struct hv_ring_buffer_info *rbi)
 {
-   u32 read;
-   u32 write;
 
rbi->ring_buffer->interrupt_mask = 0;
mb();
@@ -49,9 +47,7 @@ u32 hv_end_read(struct hv_ring_buffer_info *rbi)
 * If it is not, we raced and we need to process new
 * incoming messages.
 */
-   hv_get_ringbuffer_availbytes(rbi, &read, &write);
-
-   return read;
+   return hv_get_bytes_to_read(rbi);
 }
 
 /*
@@ -106,9 +102,6 @@ static bool hv_need_to_signal(u32 old_write, struct 
hv_ring_buffer_info *rbi)
 static bool hv_need_to_signal_on_read(struct hv_ring_buffer_info *rbi)
 {
u32 cur_write_sz;
-   u32 r_size;
-   u32 write_loc;
-   u32 read_loc = rbi->ring_buffer->read_index;
u32 pending_sz;
 
/*
@@ -125,14 +118,11 @@ static bool hv_need_to_signal_on_read(struct 
hv_ring_buffer_info *rbi)
mb();
 
pending_sz = rbi->ring_buffer->pending_send_sz;
-   write_loc = rbi->ring_buffer->write_index;
/* If the other end is not blocked on write don't bother. */
if (pending_sz == 0)
return false;
 
-   r_size = rbi->ring_datasize;
-   cur_write_sz = write_loc >= read_loc ? r_size - (write_loc - read_loc) :
-   read_loc - write_loc;
+   cur_write_sz = hv_get_bytes_to_write(rbi);
 
if (cur_write_sz >= pending_sz)
return true;
@@ -332,7 +322,6 @@ int hv_ringbuffer_write(struct hv_ring_buffer_info 
*outring_info,
 {
int i = 0;
u32 bytes_avail_towrite;
-   u32 bytes_avail_toread;
u32 totalbytes_towrite = 0;
 
u32 next_write_location;
@@ -348,9 +337,7 @@ int hv_ringbuffer_write(struct hv_ring_buffer_info 
*outring_info,
if (lock)
spin_lock_irqsave(&outring_info->ring_lock, flags);
 
-   hv_get_ringbuffer_availbytes(outring_info,
-   &bytes_avail_toread,
-   &bytes_avail_towrite);
+   bytes_avail_towrite = hv_get_bytes_to_write(outring_info);
 
/*
 * If there is only room for the packet, assume it is full.
@@ -401,7 +388,6 @@ int hv_ringbuffer_read(struct hv_ring_buffer_info 
*inring_info,
   void *buffer, u32 buflen, u32 *buffer_actual_len,
   u64 *requestid, bool *signal, bool raw)
 {
-   u32 bytes_avail_towrite;
u32 bytes_avail_toread;
u32 next_read_location = 0;
u64 prev_indices = 0;
@@ -417,10 +403,7 @@ int hv_ringbuffer_read(struct hv_ring_buffer_info 
*inring_info,
*buffer_actual_len = 0;
*requestid = 0;
 
-   hv_get_ringbuffer_availbytes(inring_info,
-   &bytes_avail_toread,
-   &bytes_avail_towrite);
-
+   bytes_avail_toread = hv_get_bytes_to_read(inring_info);
/* Make sure there is something to read */
if (bytes_avail_toread < sizeof(desc)) {
/*
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index ecd81c3..a6b053c 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -151,6 +151,33 @@ hv_get_ringbuffer_availbytes(struct hv_ring_buffer_info 
*rbi,
*read = dsize - *write;
 }
 
+static inline u32 hv_get_bytes_to_read(struct hv_ring_buffer_info *rbi)
+{
+   u32 read_loc, write_loc, dsize, read;
+
+   dsize = rbi->ring_datasize;
+   read_loc = rbi->ring_buffer->read_index;
+   write_loc = READ_ONCE(rbi->ring_buffer->write_index);
+
+   read = write_loc >= read_loc ? (write_loc - read_loc) :
+   (dsize - read_loc) + write_loc;
+
+   return read;
+}
+
+static inline u32 hv_get_bytes_to_write(struct hv_ring_buffer_info *rbi)
+{
+   u32 read_loc, write_loc, dsize, write;
+
+   dsize = rbi->ring_datasize;
+   read_loc = READ_ONCE(rbi->ring_buffer->read_index);
+   write_loc = rbi->ring_buffer->write_index;
+
+   write = write_loc >= read_loc ? dsize - (write_loc - read_loc) :
+   read_loc - write_loc;
+   return write;
+}
+
 /*
  * VMBUS version is 32 bit entity broken up into
  * two 16 bit quantities: major_number. minor_number.
-- 
1.7.4.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 4/8] Drivers: hv: vmbus: Use the new virt_xx barrier code

2016-04-05 Thread K. Y. Srinivasan
Use the virt_xx barriers that have been defined for use in virtual machines.

Signed-off-by: K. Y. Srinivasan 
---
 drivers/hv/ring_buffer.c |   14 +++---
 1 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/hv/ring_buffer.c b/drivers/hv/ring_buffer.c
index 6ea1b55..8f518af 100644
--- a/drivers/hv/ring_buffer.c
+++ b/drivers/hv/ring_buffer.c
@@ -33,14 +33,14 @@
 void hv_begin_read(struct hv_ring_buffer_info *rbi)
 {
rbi->ring_buffer->interrupt_mask = 1;
-   mb();
+   virt_mb();
 }
 
 u32 hv_end_read(struct hv_ring_buffer_info *rbi)
 {
 
rbi->ring_buffer->interrupt_mask = 0;
-   mb();
+   virt_mb();
 
/*
 * Now check to see if the ring buffer is still empty.
@@ -68,12 +68,12 @@ u32 hv_end_read(struct hv_ring_buffer_info *rbi)
 
 static bool hv_need_to_signal(u32 old_write, struct hv_ring_buffer_info *rbi)
 {
-   mb();
+   virt_mb();
if (READ_ONCE(rbi->ring_buffer->interrupt_mask))
return false;
 
/* check interrupt_mask before read_index */
-   rmb();
+   virt_rmb();
/*
 * This is the only case we need to signal when the
 * ring transitions from being empty to non-empty.
@@ -115,7 +115,7 @@ static bool hv_need_to_signal_on_read(struct 
hv_ring_buffer_info *rbi)
 * read index, we could miss sending the interrupt. Issue a full
 * memory barrier to address this.
 */
-   mb();
+   virt_mb();
 
pending_sz = READ_ONCE(rbi->ring_buffer->pending_send_sz);
/* If the other end is not blocked on write don't bother. */
@@ -371,7 +371,7 @@ int hv_ringbuffer_write(struct hv_ring_buffer_info 
*outring_info,
 sizeof(u64));
 
/* Issue a full memory barrier before updating the write index */
-   mb();
+   virt_mb();
 
/* Now, update the write location */
hv_set_next_write_location(outring_info, next_write_location);
@@ -447,7 +447,7 @@ int hv_ringbuffer_read(struct hv_ring_buffer_info 
*inring_info,
 * the writer may start writing to the read area once the read index
 * is updated.
 */
-   mb();
+   virt_mb();
 
/* Update the read index */
hv_set_next_read_location(inring_info, next_read_location);
-- 
1.7.4.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 1/8] Drivers: hv: kvp: fix IP Failover

2016-04-05 Thread K. Y. Srinivasan
From: Vitaly Kuznetsov 

Hyper-V VMs can be replicated to another hosts and there is a feature to
set different IP for replicas, it is called 'Failover TCP/IP'. When
such guest starts Hyper-V host sends it KVP_OP_SET_IP_INFO message as soon
as we finish negotiation procedure. The problem is that it can happen (and
it actually happens) before userspace daemon connects and we reply with
HV_E_FAIL to the message. As there are no repetitions we fail to set the
requested IP.

Solve the issue by postponing our reply to the negotiation message till
userspace daemon is connected. We can't wait too long as there is a
host-side timeout (cca. 75 seconds) and if we fail to reply in this time
frame the whole KVP service will become inactive. The solution is not
ideal - if it takes userspace daemon more than 60 seconds to connect
IP Failover will still fail but I don't see a solution with our current
separation between kernel and userspace parts.

Other two modules (VSS and FCOPY) don't require such delay, leave them
untouched.

Signed-off-by: Vitaly Kuznetsov 
Signed-off-by: K. Y. Srinivasan 
---
 drivers/hv/hv_kvp.c   |   31 +++
 drivers/hv/hyperv_vmbus.h |5 +
 2 files changed, 36 insertions(+), 0 deletions(-)

diff --git a/drivers/hv/hv_kvp.c b/drivers/hv/hv_kvp.c
index 9b9b370..cb1a916 100644
--- a/drivers/hv/hv_kvp.c
+++ b/drivers/hv/hv_kvp.c
@@ -78,9 +78,11 @@ static void kvp_send_key(struct work_struct *dummy);
 
 static void kvp_respond_to_host(struct hv_kvp_msg *msg, int error);
 static void kvp_timeout_func(struct work_struct *dummy);
+static void kvp_host_handshake_func(struct work_struct *dummy);
 static void kvp_register(int);
 
 static DECLARE_DELAYED_WORK(kvp_timeout_work, kvp_timeout_func);
+static DECLARE_DELAYED_WORK(kvp_host_handshake_work, kvp_host_handshake_func);
 static DECLARE_WORK(kvp_sendkey_work, kvp_send_key);
 
 static const char kvp_devname[] = "vmbus/hv_kvp";
@@ -130,6 +132,11 @@ static void kvp_timeout_func(struct work_struct *dummy)
hv_poll_channel(kvp_transaction.recv_channel, kvp_poll_wrapper);
 }
 
+static void kvp_host_handshake_func(struct work_struct *dummy)
+{
+   hv_poll_channel(kvp_transaction.recv_channel, hv_kvp_onchannelcallback);
+}
+
 static int kvp_handle_handshake(struct hv_kvp_msg *msg)
 {
switch (msg->kvp_hdr.operation) {
@@ -154,6 +161,12 @@ static int kvp_handle_handshake(struct hv_kvp_msg *msg)
pr_debug("KVP: userspace daemon ver. %d registered\n",
 KVP_OP_REGISTER);
kvp_register(dm_reg_value);
+
+   /*
+* If we're still negotiating with the host cancel the timeout
+* work to not poll the channel twice.
+*/
+   cancel_delayed_work_sync(&kvp_host_handshake_work);
hv_poll_channel(kvp_transaction.recv_channel, kvp_poll_wrapper);
 
return 0;
@@ -594,7 +607,22 @@ void hv_kvp_onchannelcallback(void *context)
struct icmsg_negotiate *negop = NULL;
int util_fw_version;
int kvp_srv_version;
+   static enum {NEGO_NOT_STARTED,
+NEGO_IN_PROGRESS,
+NEGO_FINISHED} host_negotiatied = NEGO_NOT_STARTED;
 
+   if (host_negotiatied == NEGO_NOT_STARTED &&
+   kvp_transaction.state < HVUTIL_READY) {
+   /*
+* If userspace daemon is not connected and host is asking
+* us to negotiate we need to delay to not lose messages.
+* This is important for Failover IP setting.
+*/
+   host_negotiatied = NEGO_IN_PROGRESS;
+   schedule_delayed_work(&kvp_host_handshake_work,
+ HV_UTIL_NEGO_TIMEOUT * HZ);
+   return;
+   }
if (kvp_transaction.state > HVUTIL_READY)
return;
 
@@ -672,6 +700,8 @@ void hv_kvp_onchannelcallback(void *context)
vmbus_sendpacket(channel, recv_buffer,
   recvlen, requestid,
   VM_PKT_DATA_INBAND, 0);
+
+   host_negotiatied = NEGO_FINISHED;
}
 
 }
@@ -708,6 +738,7 @@ hv_kvp_init(struct hv_util_service *srv)
 void hv_kvp_deinit(void)
 {
kvp_transaction.state = HVUTIL_DEVICE_DYING;
+   cancel_delayed_work_sync(&kvp_host_handshake_work);
cancel_delayed_work_sync(&kvp_timeout_work);
cancel_work_sync(&kvp_sendkey_work);
hvutil_transport_destroy(hvt);
diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h
index 12321b9..8b07f9c 100644
--- a/drivers/hv/hyperv_vmbus.h
+++ b/drivers/hv/hyperv_vmbus.h
@@ -36,6 +36,11 @@
 #define HV_UTIL_TIMEOUT 30
 
 /*
+ * Timeout for guest-host handshake for services.
+ */
+#define HV_UTIL_NEGO_TIMEOUT 60
+
+/*
  * The below CPUID leaves are present if VersionAndFeatures.HypervisorPresent
  * is set by CPUID(HVCPUID_VERSION_FEATURES).
  */
-- 
1.7.4.1

___
devel mailing

[PATCH 8/8] Drivers: hv: vmbus: handle various crash scenarios

2016-04-05 Thread K. Y. Srinivasan
From: Vitaly Kuznetsov <[mailto:vkuzn...@redhat.com]>

Kdump keeps biting. Turns out CHANNELMSG_UNLOAD_RESPONSE is always
delivered to the CPU which was used for initial contact or to CPU0
depending on host version. vmbus_wait_for_unload() doesn't account for
the fact that in case we're crashing on some other CPU we won't get the
CHANNELMSG_UNLOAD_RESPONSE message and our wait on the current CPU will
never end.

Do the following:
1) Check for completion_done() in the loop. In case interrupt handler is
   still alive we'll get the confirmation we need.

2) Read message pages for all CPUs message page as we're unsure where
   CHANNELMSG_UNLOAD_RESPONSE is going to be delivered to. We can race with
   still-alive interrupt handler doing the same, add cmpxchg() to
   vmbus_signal_eom() to not lose CHANNELMSG_UNLOAD_RESPONSE message.

3) Cleanup message pages on all CPUs. This is required (at least for the
   current CPU as we're clearing CPU0 messages now but we may want to bring
   up additional CPUs on crash) as new messages won't be delivered till we
   consume what's pending. On boot we'll place message pages somewhere else
   and we won't be able to read stale messages.

Signed-off-by: Vitaly Kuznetsov 
Signed-off-by: K. Y. Srinivasan 
---
 drivers/hv/channel_mgmt.c |   58 +---
 drivers/hv/hyperv_vmbus.h |   16 +++-
 drivers/hv/vmbus_drv.c|7 +++--
 3 files changed, 61 insertions(+), 20 deletions(-)

diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
index 38b682ba..b6c1211 100644
--- a/drivers/hv/channel_mgmt.c
+++ b/drivers/hv/channel_mgmt.c
@@ -597,27 +597,55 @@ static void init_vp_index(struct vmbus_channel *channel, 
u16 dev_type)
 
 static void vmbus_wait_for_unload(void)
 {
-   int cpu = smp_processor_id();
-   void *page_addr = hv_context.synic_message_page[cpu];
-   struct hv_message *msg = (struct hv_message *)page_addr +
- VMBUS_MESSAGE_SINT;
+   int cpu;
+   void *page_addr;
+   struct hv_message *msg;
struct vmbus_channel_message_header *hdr;
-   bool unloaded = false;
+   u32 message_type;
 
+   /*
+* CHANNELMSG_UNLOAD_RESPONSE is always delivered to the CPU which was
+* used for initial contact or to CPU0 depending on host version. When
+* we're crashing on a different CPU let's hope that IRQ handler on
+* the cpu which receives CHANNELMSG_UNLOAD_RESPONSE is still
+* functional and vmbus_unload_response() will complete
+* vmbus_connection.unload_event. If not, the last thing we can do is
+* read message pages for all CPUs directly.
+*/
while (1) {
-   if (READ_ONCE(msg->header.message_type) == HVMSG_NONE) {
-   mdelay(10);
-   continue;
-   }
+   if (completion_done(&vmbus_connection.unload_event))
+   break;
 
-   hdr = (struct vmbus_channel_message_header *)msg->u.payload;
-   if (hdr->msgtype == CHANNELMSG_UNLOAD_RESPONSE)
-   unloaded = true;
+   for_each_online_cpu(cpu) {
+   page_addr = hv_context.synic_message_page[cpu];
+   msg = (struct hv_message *)page_addr +
+   VMBUS_MESSAGE_SINT;
 
-   vmbus_signal_eom(msg);
+   message_type = READ_ONCE(msg->header.message_type);
+   if (message_type == HVMSG_NONE)
+   continue;
 
-   if (unloaded)
-   break;
+   hdr = (struct vmbus_channel_message_header *)
+   msg->u.payload;
+
+   if (hdr->msgtype == CHANNELMSG_UNLOAD_RESPONSE)
+   complete(&vmbus_connection.unload_event);
+
+   vmbus_signal_eom(msg, message_type);
+   }
+
+   mdelay(10);
+   }
+
+   /*
+* We're crashing and already got the UNLOAD_RESPONSE, cleanup all
+* maybe-pending messages on all CPUs to be able to receive new
+* messages after we reconnect.
+*/
+   for_each_online_cpu(cpu) {
+   page_addr = hv_context.synic_message_page[cpu];
+   msg = (struct hv_message *)page_addr + VMBUS_MESSAGE_SINT;
+   msg->header.message_type = HVMSG_NONE;
}
 }
 
diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h
index e5203e4..718b5c7 100644
--- a/drivers/hv/hyperv_vmbus.h
+++ b/drivers/hv/hyperv_vmbus.h
@@ -625,9 +625,21 @@ extern struct vmbus_channel_message_table_entry
channel_message_table[CHANNELMSG_COUNT];
 
 /* Free the message slot and signal end-of-message if required */
-static inline void vmbus_signal_eom(struct hv_message *msg)
+static inline void vmbus_signal_eom(struct hv_message *msg, u32 ol

[PATCH 6/8] Drivers: hv: vmbus: Move some ring buffer functions to hyperv.h

2016-04-05 Thread K. Y. Srinivasan
In preparation for implementing APIs for in-place consumption of VMBUS
packets, movve some ring buffer functionality into hyperv.h

Signed-off-by: K. Y. Srinivasan 
---
 drivers/hv/ring_buffer.c |   55 --
 include/linux/hyperv.h   |   54 +
 2 files changed, 54 insertions(+), 55 deletions(-)

diff --git a/drivers/hv/ring_buffer.c b/drivers/hv/ring_buffer.c
index 8f518af..dd255c9 100644
--- a/drivers/hv/ring_buffer.c
+++ b/drivers/hv/ring_buffer.c
@@ -84,52 +84,6 @@ static bool hv_need_to_signal(u32 old_write, struct 
hv_ring_buffer_info *rbi)
return false;
 }
 
-/*
- * To optimize the flow management on the send-side,
- * when the sender is blocked because of lack of
- * sufficient space in the ring buffer, potential the
- * consumer of the ring buffer can signal the producer.
- * This is controlled by the following parameters:
- *
- * 1. pending_send_sz: This is the size in bytes that the
- *producer is trying to send.
- * 2. The feature bit feat_pending_send_sz set to indicate if
- *the consumer of the ring will signal when the ring
- *state transitions from being full to a state where
- *there is room for the producer to send the pending packet.
- */
-
-static bool hv_need_to_signal_on_read(struct hv_ring_buffer_info *rbi)
-{
-   u32 cur_write_sz;
-   u32 pending_sz;
-
-   /*
-* Issue a full memory barrier before making the signaling decision.
-* Here is the reason for having this barrier:
-* If the reading of the pend_sz (in this function)
-* were to be reordered and read before we commit the new read
-* index (in the calling function)  we could
-* have a problem. If the host were to set the pending_sz after we
-* have sampled pending_sz and go to sleep before we commit the
-* read index, we could miss sending the interrupt. Issue a full
-* memory barrier to address this.
-*/
-   virt_mb();
-
-   pending_sz = READ_ONCE(rbi->ring_buffer->pending_send_sz);
-   /* If the other end is not blocked on write don't bother. */
-   if (pending_sz == 0)
-   return false;
-
-   cur_write_sz = hv_get_bytes_to_write(rbi);
-
-   if (cur_write_sz >= pending_sz)
-   return true;
-
-   return false;
-}
-
 /* Get the next write location for the specified ring buffer. */
 static inline u32
 hv_get_next_write_location(struct hv_ring_buffer_info *ring_info)
@@ -180,15 +134,6 @@ hv_set_next_read_location(struct hv_ring_buffer_info 
*ring_info,
ring_info->ring_buffer->read_index = next_read_location;
 }
 
-
-/* Get the start of the ring buffer. */
-static inline void *
-hv_get_ring_buffer(struct hv_ring_buffer_info *ring_info)
-{
-   return (void *)ring_info->ring_buffer->buffer;
-}
-
-
 /* Get the size of the ring buffer. */
 static inline u32
 hv_get_ring_buffersize(struct hv_ring_buffer_info *ring_info)
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index 4adeb6e..6797a30 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -1366,4 +1366,58 @@ extern __u32 vmbus_proto_version;
 int vmbus_send_tl_connect_request(const uuid_le *shv_guest_servie_id,
  const uuid_le *shv_host_servie_id);
 void vmbus_set_event(struct vmbus_channel *channel);
+
+/* Get the start of the ring buffer. */
+static inline void *
+hv_get_ring_buffer(struct hv_ring_buffer_info *ring_info)
+{
+   return (void *)ring_info->ring_buffer->buffer;
+}
+
+/*
+ * To optimize the flow management on the send-side,
+ * when the sender is blocked because of lack of
+ * sufficient space in the ring buffer, potential the
+ * consumer of the ring buffer can signal the producer.
+ * This is controlled by the following parameters:
+ *
+ * 1. pending_send_sz: This is the size in bytes that the
+ *producer is trying to send.
+ * 2. The feature bit feat_pending_send_sz set to indicate if
+ *the consumer of the ring will signal when the ring
+ *state transitions from being full to a state where
+ *there is room for the producer to send the pending packet.
+ */
+
+static inline  bool hv_need_to_signal_on_read(struct hv_ring_buffer_info *rbi)
+{
+   u32 cur_write_sz;
+   u32 pending_sz;
+
+   /*
+* Issue a full memory barrier before making the signaling decision.
+* Here is the reason for having this barrier:
+* If the reading of the pend_sz (in this function)
+* were to be reordered and read before we commit the new read
+* index (in the calling function)  we could
+* have a problem. If the host were to set the pending_sz after we
+* have sampled pending_sz and go to sleep before we commit the
+* read index, we could miss sending the interrupt. Issue a full
+* memory barrier to address this.
+*/
+   virt_mb();
+
+   pending_sz = READ_ON

[PATCH 5/8] Drivers: hv: vmbus: Export the vmbus_set_event() API

2016-04-05 Thread K. Y. Srinivasan
In preparation for moving some ring buffer functionality out of the
vmbus driver, export the API for signaling the host.

Signed-off-by: K. Y. Srinivasan 
---
 drivers/hv/connection.c   |1 +
 drivers/hv/hyperv_vmbus.h |2 --
 include/linux/hyperv.h|1 +
 3 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/hv/connection.c b/drivers/hv/connection.c
index d02f137..fcf8a02 100644
--- a/drivers/hv/connection.c
+++ b/drivers/hv/connection.c
@@ -495,3 +495,4 @@ void vmbus_set_event(struct vmbus_channel *channel)
 
hv_do_hypercall(HVCALL_SIGNAL_EVENT, channel->sig_event, NULL);
 }
+EXPORT_SYMBOL_GPL(vmbus_set_event);
diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h
index 8b07f9c..e5203e4 100644
--- a/drivers/hv/hyperv_vmbus.h
+++ b/drivers/hv/hyperv_vmbus.h
@@ -672,8 +672,6 @@ void vmbus_disconnect(void);
 
 int vmbus_post_msg(void *buffer, size_t buflen);
 
-void vmbus_set_event(struct vmbus_channel *channel);
-
 void vmbus_on_event(unsigned long data);
 void vmbus_on_msg_dpc(unsigned long data);
 
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index a6b053c..4adeb6e 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -1365,4 +1365,5 @@ extern __u32 vmbus_proto_version;
 
 int vmbus_send_tl_connect_request(const uuid_le *shv_guest_servie_id,
  const uuid_le *shv_host_servie_id);
+void vmbus_set_event(struct vmbus_channel *channel);
 #endif /* _HYPERV_H */
-- 
1.7.4.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 7/8] Drivers: hv: vmbus: Implement APIs to support "in place" consumption of vmbus packets

2016-04-05 Thread K. Y. Srinivasan
Implement APIs for in-place consumption of vmbus packets. Currently, each
packet is copied and processed one at a time and as part of processing
each packet we potentially may signal the host (if it is waiting for
room to produce a packet).

These APIs help batched in-place processing of vmbus packets.
We also optimize host signaling by having a separate API to signal
the end of in-place consumption. With netvsc using these APIs,
on an iperf run on average I see about 20X reduction in checks to
signal the host.

Signed-off-by: K. Y. Srinivasan 
---
 drivers/hv/ring_buffer.c |1 +
 include/linux/hyperv.h   |   86 ++
 2 files changed, 87 insertions(+), 0 deletions(-)

diff --git a/drivers/hv/ring_buffer.c b/drivers/hv/ring_buffer.c
index dd255c9..fe586bf 100644
--- a/drivers/hv/ring_buffer.c
+++ b/drivers/hv/ring_buffer.c
@@ -132,6 +132,7 @@ hv_set_next_read_location(struct hv_ring_buffer_info 
*ring_info,
u32 next_read_location)
 {
ring_info->ring_buffer->read_index = next_read_location;
+   ring_info->priv_read_index = next_read_location;
 }
 
 /* Get the size of the ring buffer. */
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index 6797a30..b10954a 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -126,6 +126,8 @@ struct hv_ring_buffer_info {
 
u32 ring_datasize;  /* < ring_size */
u32 ring_data_startoffset;
+   u32 priv_write_index;
+   u32 priv_read_index;
 };
 
 /*
@@ -1420,4 +1422,88 @@ static inline  bool hv_need_to_signal_on_read(struct 
hv_ring_buffer_info *rbi)
return false;
 }
 
+/*
+ * An API to support in-place processing of incoming VMBUS packets.
+ */
+#define VMBUS_PKT_TRAILER  8
+
+static inline struct vmpacket_descriptor *
+get_next_pkt_raw(struct vmbus_channel *channel)
+{
+   struct hv_ring_buffer_info *ring_info = &channel->inbound;
+   u32 read_loc = ring_info->priv_read_index;
+   void *ring_buffer = hv_get_ring_buffer(ring_info);
+   struct vmpacket_descriptor *cur_desc;
+   u32 packetlen;
+   u32 dsize = ring_info->ring_datasize;
+   u32 delta = read_loc - ring_info->ring_buffer->read_index;
+   u32 bytes_avail_toread = (hv_get_bytes_to_read(ring_info) - delta);
+
+   if (bytes_avail_toread < sizeof(struct vmpacket_descriptor))
+   return NULL;
+
+   if ((read_loc + sizeof(*cur_desc)) > dsize)
+   return NULL;
+
+   cur_desc = ring_buffer + read_loc;
+   packetlen = cur_desc->len8 << 3;
+
+   /*
+* If the packet under consideration is wrapping around,
+* return failure.
+*/
+   if ((read_loc + packetlen + VMBUS_PKT_TRAILER) > (dsize - 1))
+   return NULL;
+
+   return cur_desc;
+}
+
+/*
+ * A helper function to step through packets "in-place"
+ * This API is to be called after each successful call
+ * get_next_pkt_raw().
+ */
+static inline void put_pkt_raw(struct vmbus_channel *channel,
+   struct vmpacket_descriptor *desc)
+{
+   struct hv_ring_buffer_info *ring_info = &channel->inbound;
+   u32 read_loc = ring_info->priv_read_index;
+   u32 packetlen = desc->len8 << 3;
+   u32 dsize = ring_info->ring_datasize;
+
+   if ((read_loc + packetlen + VMBUS_PKT_TRAILER) > dsize)
+   BUG();
+   /*
+* Include the packet trailer.
+*/
+   ring_info->priv_read_index += packetlen + VMBUS_PKT_TRAILER;
+}
+
+/*
+ * This call commits the read index and potentially signals the host.
+ * Here is the pattern for using the "in-place" consumption APIs:
+ *
+ * while (get_next_pkt_raw() {
+ * process the packet "in-place";
+ * put_pkt_raw();
+ * }
+ * if (packets processed in place)
+ * commit_rd_index();
+ */
+static inline void commit_rd_index(struct vmbus_channel *channel)
+{
+   struct hv_ring_buffer_info *ring_info = &channel->inbound;
+   /*
+* Make sure all reads are done before we update the read index since
+* the writer may start writing to the read area once the read index
+* is updated.
+*/
+   virt_rmb();
+   ring_info->ring_buffer->read_index = ring_info->priv_read_index;
+
+   if (hv_need_to_signal_on_read(ring_info))
+   vmbus_set_event(channel);
+}
+
+
 #endif /* _HYPERV_H */
-- 
1.7.4.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 3/8] Drivers: hv: vmbus: Use READ_ONCE() to read variables that are volatile

2016-04-05 Thread K. Y. Srinivasan
Use the READ_ONCE macro to access variabes that can change asynchronously.
This is the recommended mechanism for dealing with "unsafe" compiler
optimizations.

Signed-off-by: K. Y. Srinivasan 
---
 drivers/hv/ring_buffer.c |6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/hv/ring_buffer.c b/drivers/hv/ring_buffer.c
index 544362c..6ea1b55 100644
--- a/drivers/hv/ring_buffer.c
+++ b/drivers/hv/ring_buffer.c
@@ -69,7 +69,7 @@ u32 hv_end_read(struct hv_ring_buffer_info *rbi)
 static bool hv_need_to_signal(u32 old_write, struct hv_ring_buffer_info *rbi)
 {
mb();
-   if (rbi->ring_buffer->interrupt_mask)
+   if (READ_ONCE(rbi->ring_buffer->interrupt_mask))
return false;
 
/* check interrupt_mask before read_index */
@@ -78,7 +78,7 @@ static bool hv_need_to_signal(u32 old_write, struct 
hv_ring_buffer_info *rbi)
 * This is the only case we need to signal when the
 * ring transitions from being empty to non-empty.
 */
-   if (old_write == rbi->ring_buffer->read_index)
+   if (old_write == READ_ONCE(rbi->ring_buffer->read_index))
return true;
 
return false;
@@ -117,7 +117,7 @@ static bool hv_need_to_signal_on_read(struct 
hv_ring_buffer_info *rbi)
 */
mb();
 
-   pending_sz = rbi->ring_buffer->pending_send_sz;
+   pending_sz = READ_ONCE(rbi->ring_buffer->pending_send_sz);
/* If the other end is not blocked on write don't bother. */
if (pending_sz == 0)
return false;
-- 
1.7.4.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 0/8] Drivers: hv: Miscellaneous vmbus and util driver fixes

2016-04-05 Thread K. Y. Srinivasan
Cleanup the ringbuffer code and implement APIs for "in place" consumption.
This patchset also includes some other miscellaneous fixes.

K. Y. Srinivasan (6):
  Drivers: hv: vmbus: Introduce functions for estimating room in the
ring buffer
  Drivers: hv: vmbus: Use READ_ONCE() to read variables that are
volatile
  Drivers: hv: vmbus: Use the new virt_xx barrier code
  Drivers: hv: vmbus: Export the vmbus_set_event() API
  Drivers: hv: vmbus: Move some ring buffer functions to hyperv.h
  Drivers: hv: vmbus: Implement APIs to support "in place" consumption
of vmbus packets

Vitaly Kuznetsov (2):
  Drivers: hv: kvp: fix IP Failover
  Drivers: hv: vmbus: handle various crash scenarios

 drivers/hv/channel_mgmt.c |   58 
 drivers/hv/connection.c   |1 +
 drivers/hv/hv_kvp.c   |   31 
 drivers/hv/hyperv_vmbus.h |   23 +-
 drivers/hv/ring_buffer.c  |   95 +++--
 drivers/hv/vmbus_drv.c|7 +-
 include/linux/hyperv.h|  168 +
 7 files changed, 278 insertions(+), 105 deletions(-)

-- 
1.7.4.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


RE: [PATCH v4 3/7] drivers:hv: Use new vmbus_mmio_free() from client drivers.

2016-04-05 Thread Jake Oshins
> -Original Message-
> From: Bjorn Helgaas [mailto:helg...@kernel.org]
> Sent: Tuesday, April 5, 2016 11:00 AM
> To: Jake Oshins 
> Cc: linux-...@vger.kernel.org; gre...@linuxfoundation.org; KY Srinivasan
> ; linux-ker...@vger.kernel.org;
> de...@linuxdriverproject.org; o...@aepfle.de; a...@canonical.com;
> vkuzn...@redhat.com; Haiyang Zhang ; Hadden
> Hoppert 
> Subject: Re: [PATCH v4 3/7] drivers:hv: Use new vmbus_mmio_free() from
> client drivers.
> 
> Hi Jake,
> 
> On Fri, Apr 01, 2016 at 05:47:43PM -0700, Jake Oshins wrote:
> > This patch modifies all the callers of vmbus_mmio_allocate()
> > to call vmbus_mmio_free() instead of release_mem_region().
> 
> This changelog merely restates the C code.  Presumably there's some
> important difference between release_mem_region() and
> vmbus_mmio_free(), and we need a hint about what that is.
> 
> Oh, I see, there actually is no difference *yet*, but it's coming.
> I'd combine this with patch 2.  Then the patch is obviously correct
> all by itself, and the changelog for patch 2 makes clear what's
> happening.
> 
> In changelogs, don't bother with "this patch does" or "this function
> is introduced."  The context is obvious because the changelog is part
> of the commit.  Write imperative sentences, e.g., "Call
> vmbus_mmio_free() instead of release_mem_region()."
> 

Will do.  Thanks.

-- Jake Oshins

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


RE: [PATCH v4 3/7] drivers:hv: Use new vmbus_mmio_free() from client drivers.

2016-04-05 Thread KY Srinivasan


> -Original Message-
> From: Bjorn Helgaas [mailto:helg...@kernel.org]
> Sent: Tuesday, April 5, 2016 11:00 AM
> To: Jake Oshins 
> Cc: linux-...@vger.kernel.org; gre...@linuxfoundation.org; KY Srinivasan
> ; linux-ker...@vger.kernel.org;
> de...@linuxdriverproject.org; o...@aepfle.de; a...@canonical.com;
> vkuzn...@redhat.com; Haiyang Zhang ; Hadden
> Hoppert 
> Subject: Re: [PATCH v4 3/7] drivers:hv: Use new vmbus_mmio_free() from
> client drivers.
> 
> Hi Jake,
> 
> On Fri, Apr 01, 2016 at 05:47:43PM -0700, Jake Oshins wrote:
> > This patch modifies all the callers of vmbus_mmio_allocate()
> > to call vmbus_mmio_free() instead of release_mem_region().
> 
> This changelog merely restates the C code.  Presumably there's some
> important difference between release_mem_region() and
> vmbus_mmio_free(), and we need a hint about what that is.
> 
> Oh, I see, there actually is no difference *yet*, but it's coming.
> I'd combine this with patch 2.  Then the patch is obviously correct
> all by itself, and the changelog for patch 2 makes clear what's
> happening.
> 
> In changelogs, don't bother with "this patch does" or "this function
> is introduced."  The context is obvious because the changelog is part
> of the commit.  Write imperative sentences, e.g., "Call
> vmbus_mmio_free() instead of release_mem_region()."
> 
> > Signed-off-by: Jake Oshins 
> 
> I think this is the only change that touches PCI, so I assume this
> series will be merged by somebody else.
> 
> Acked-by: Bjorn Helgaas 

I am hoping this will go through Greg's tree.

K. Y
> 
> > ---
> >  drivers/pci/host/pci-hyperv.c   | 14 +++---
> >  drivers/video/fbdev/hyperv_fb.c |  4 ++--
> >  2 files changed, 9 insertions(+), 9 deletions(-)
> >
> > diff --git a/drivers/pci/host/pci-hyperv.c b/drivers/pci/host/pci-hyperv.c
> > index ed651ba..f2559b6 100644
> > --- a/drivers/pci/host/pci-hyperv.c
> > +++ b/drivers/pci/host/pci-hyperv.c
> > @@ -1795,14 +1795,14 @@ static void hv_pci_free_bridge_windows(struct
> hv_pcibus_device *hbus)
> >
> > if (hbus->low_mmio_space && hbus->low_mmio_res) {
> > hbus->low_mmio_res->flags |= IORESOURCE_BUSY;
> > -   release_mem_region(hbus->low_mmio_res->start,
> > -  resource_size(hbus->low_mmio_res));
> > +   vmbus_free_mmio(hbus->low_mmio_res->start,
> > +   resource_size(hbus->low_mmio_res));
> > }
> >
> > if (hbus->high_mmio_space && hbus->high_mmio_res) {
> > hbus->high_mmio_res->flags |= IORESOURCE_BUSY;
> > -   release_mem_region(hbus->high_mmio_res->start,
> > -  resource_size(hbus->high_mmio_res));
> > +   vmbus_free_mmio(hbus->high_mmio_res->start,
> > +   resource_size(hbus->high_mmio_res));
> > }
> >  }
> >
> > @@ -1880,8 +1880,8 @@ static int hv_pci_allocate_bridge_windows(struct
> hv_pcibus_device *hbus)
> >
> >  release_low_mmio:
> > if (hbus->low_mmio_res) {
> > -   release_mem_region(hbus->low_mmio_res->start,
> > -  resource_size(hbus->low_mmio_res));
> > +   vmbus_free_mmio(hbus->low_mmio_res->start,
> > +   resource_size(hbus->low_mmio_res));
> > }
> >
> > return ret;
> > @@ -1924,7 +1924,7 @@ static int hv_allocate_config_window(struct
> hv_pcibus_device *hbus)
> >
> >  static void hv_free_config_window(struct hv_pcibus_device *hbus)
> >  {
> > -   release_mem_region(hbus->mem_config->start,
> PCI_CONFIG_MMIO_LENGTH);
> > +   vmbus_free_mmio(hbus->mem_config->start,
> PCI_CONFIG_MMIO_LENGTH);
> >  }
> >
> >  /**
> > diff --git a/drivers/video/fbdev/hyperv_fb.c
> b/drivers/video/fbdev/hyperv_fb.c
> > index e2451bd..2fd49b2 100644
> > --- a/drivers/video/fbdev/hyperv_fb.c
> > +++ b/drivers/video/fbdev/hyperv_fb.c
> > @@ -743,7 +743,7 @@ static int hvfb_getmem(struct hv_device *hdev,
> struct fb_info *info)
> >  err3:
> > iounmap(fb_virt);
> >  err2:
> > -   release_mem_region(par->mem->start, screen_fb_size);
> > +   vmbus_free_mmio(par->mem->start, screen_fb_size);
> > par->mem = NULL;
> >  err1:
> > if (!gen2vm)
> > @@ -758,7 +758,7 @@ static void hvfb_putmem(struct fb_info *info)
> > struct hvfb_par *par = info->par;
> >
> > iounmap(info->screen_base);
> > -   release_mem_region(par->mem->start, screen_fb_size);
> > +   vmbus_free_mmio(par->mem->start, screen_fb_size);
> > par->mem = NULL;
> >  }
> >
> > --
> > 1.9.1
> >
> > --
> > To unsubscribe from this list: send the line "unsubscribe linux-pci" in
> > the body of a message to majord...@vger.kernel.org
> > More majordomo info at
> https://na01.safelinks.protection.outlook.com/?url=http%3a%2f%2fvger.ker
> nel.org%2fmajordomo-
> info.html&data=01%7c01%7ckys%40microsoft.com%7cf391db0d7312429368e
> 908d35d7c17ed%7c72f988bf86f141af91ab2d7cd011db47%7c1&sdata=bH6jnta
> OKCSn%2fZw%2bCN1P9wV9%2bRk0om8hw4evDezjR0Q%3d
___

Re: [PATCH v10 3/3] staging/android: refactor SYNC IOCTLs

2016-04-05 Thread Gustavo Padovan
Hi Greg,

Any comments on this?

Thanks,

Gustavo

2016-03-18 Gustavo Padovan :

> From: Gustavo Padovan 
> 
> Change SYNC_IOC_FILE_INFO (former SYNC_IOC_FENCE_INFO) behaviour to avoid
> future API breaks and optimize buffer allocation.
> 
> Now num_fences can be filled by the caller to inform how many fences it
> wants to retrieve from the kernel. If the num_fences passed is greater
> than zero info->sync_fence_info should point to a buffer with enough space
> to fit all fences.
> 
> However if num_fences passed to the kernel is 0, the kernel will reply
> with number of fences of the sync_file.
> 
> Sending first an ioctl with num_fences = 0 can optimize buffer allocation,
> in a first call with num_fences = 0 userspace will receive the actual
> number of fences in the num_fences filed.
> 
> Then it can allocate a buffer with the correct size on sync_fence_info and
> call SYNC_IOC_FILE_INFO again, but now with the actual value of num_fences
> in the sync_file.
> 
> info->sync_fence_info was converted to __u64 pointer to prevent 32bit
> compatibility issues. And a flags member was added.
> 
> An example userspace code for the later would be:
> 
>   struct sync_file_info *info;
>   int err, size, num_fences;
> 
>   info = malloc(sizeof(*info));
> 
>   info.flags = 0;
>   err = ioctl(fd, SYNC_IOC_FILE_INFO, info);
>   num_fences = info->num_fences;
> 
>   if (num_fences) {
>   info.flags = 0;
>   size = sizeof(struct sync_fence_info) * num_fences;
>   info->num_fences = num_fences;
>   info->sync_fence_info = (uint64_t) calloc(num_fences,
> sizeof(struct 
> sync_fence_info));
> 
>   err = ioctl(fd, SYNC_IOC_FILE_INFO, info);
>   }
> 
> Finally the IOCTLs numbers were changed to avoid any potential old
> userspace running the old API to get weird errors. Changing the opcodes
> will make them fail right away. This is just a precaution, there no
> upstream users of these interfaces yet and the only user is Android, but
> we don't expect anyone trying to run android userspace and all it
> dependencies on top of upstream kernels.
> 
> Signed-off-by: Gustavo Padovan 
> Reviewed-by: Maarten Lankhorst 
> Acked-by: Greg Hackmann 
> Acked-by: Rob Clark 
> Acked-by: Daniel Vetter 
> 
> ---
> v2: fix fence_info memory leak
> 
> v3: Comments from Emil Velikov
>   - improve commit message
>   - remove __u64 cast
>   - remove check for output fields in file_info
>   - clean up sync_fill_fence_info()
> 
> Comments from Maarten Lankhorst
>   - remove in.num_fences && !in.sync_fence_info check
>   - remove info->len and use only num_fences to calculate size
> 
> Comments from Dan Carpenter
>   - fix info->sync_fence_info documentation
> 
> v4: remove allocated struct sync_file_info (comment from Maarten)
> 
> v5: merge all commits that were changing the ABI
> 
> v6: fix -Wint-to-pointer-cast error on info.sync_fence_info
> ---
>  drivers/staging/android/sync.c  | 76 
> -
>  drivers/staging/android/uapi/sync.h | 36 +-
>  2 files changed, 67 insertions(+), 45 deletions(-)
> 
> diff --git a/drivers/staging/android/sync.c b/drivers/staging/android/sync.c
> index 3a8f210..f9c6094 100644
> --- a/drivers/staging/android/sync.c
> +++ b/drivers/staging/android/sync.c
> @@ -445,6 +445,11 @@ static long sync_file_ioctl_merge(struct sync_file 
> *sync_file,
>   goto err_put_fd;
>   }
>  
> + if (data.flags || data.pad) {
> + err = -EINVAL;
> + goto err_put_fd;
> + }
> +
>   fence2 = sync_file_fdget(data.fd2);
>   if (!fence2) {
>   err = -ENOENT;
> @@ -479,13 +484,9 @@ err_put_fd:
>   return err;
>  }
>  
> -static int sync_fill_fence_info(struct fence *fence, void *data, int size)
> +static void sync_fill_fence_info(struct fence *fence,
> + struct sync_fence_info *info)
>  {
> - struct sync_fence_info *info = data;
> -
> - if (size < sizeof(*info))
> - return -ENOMEM;
> -
>   strlcpy(info->obj_name, fence->ops->get_timeline_name(fence),
>   sizeof(info->obj_name));
>   strlcpy(info->driver_name, fence->ops->get_driver_name(fence),
> @@ -495,58 +496,63 @@ static int sync_fill_fence_info(struct fence *fence, 
> void *data, int size)
>   else
>   info->status = 0;
>   info->timestamp_ns = ktime_to_ns(fence->timestamp);
> -
> - return sizeof(*info);
>  }
>  
>  static long sync_file_ioctl_fence_info(struct sync_file *sync_file,
>   unsigned long arg)
>  {
> - struct sync_file_info *info;
> + struct sync_file_info info;
> + struct sync_fence_info *fence_info = NULL;
>   __u32 size;
> - __u32 len = 0;
>   int ret, i;
>  
> - if (copy_from_user(&size, (void __user *)arg, sizeo

Re: [PATCH v4 3/7] drivers:hv: Use new vmbus_mmio_free() from client drivers.

2016-04-05 Thread Bjorn Helgaas
Hi Jake,

On Fri, Apr 01, 2016 at 05:47:43PM -0700, Jake Oshins wrote:
> This patch modifies all the callers of vmbus_mmio_allocate()
> to call vmbus_mmio_free() instead of release_mem_region().

This changelog merely restates the C code.  Presumably there's some
important difference between release_mem_region() and
vmbus_mmio_free(), and we need a hint about what that is.

Oh, I see, there actually is no difference *yet*, but it's coming.
I'd combine this with patch 2.  Then the patch is obviously correct
all by itself, and the changelog for patch 2 makes clear what's
happening.

In changelogs, don't bother with "this patch does" or "this function
is introduced."  The context is obvious because the changelog is part
of the commit.  Write imperative sentences, e.g., "Call
vmbus_mmio_free() instead of release_mem_region()."

> Signed-off-by: Jake Oshins 

I think this is the only change that touches PCI, so I assume this
series will be merged by somebody else.

Acked-by: Bjorn Helgaas 

> ---
>  drivers/pci/host/pci-hyperv.c   | 14 +++---
>  drivers/video/fbdev/hyperv_fb.c |  4 ++--
>  2 files changed, 9 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/pci/host/pci-hyperv.c b/drivers/pci/host/pci-hyperv.c
> index ed651ba..f2559b6 100644
> --- a/drivers/pci/host/pci-hyperv.c
> +++ b/drivers/pci/host/pci-hyperv.c
> @@ -1795,14 +1795,14 @@ static void hv_pci_free_bridge_windows(struct 
> hv_pcibus_device *hbus)
>  
>   if (hbus->low_mmio_space && hbus->low_mmio_res) {
>   hbus->low_mmio_res->flags |= IORESOURCE_BUSY;
> - release_mem_region(hbus->low_mmio_res->start,
> -resource_size(hbus->low_mmio_res));
> + vmbus_free_mmio(hbus->low_mmio_res->start,
> + resource_size(hbus->low_mmio_res));
>   }
>  
>   if (hbus->high_mmio_space && hbus->high_mmio_res) {
>   hbus->high_mmio_res->flags |= IORESOURCE_BUSY;
> - release_mem_region(hbus->high_mmio_res->start,
> -resource_size(hbus->high_mmio_res));
> + vmbus_free_mmio(hbus->high_mmio_res->start,
> + resource_size(hbus->high_mmio_res));
>   }
>  }
>  
> @@ -1880,8 +1880,8 @@ static int hv_pci_allocate_bridge_windows(struct 
> hv_pcibus_device *hbus)
>  
>  release_low_mmio:
>   if (hbus->low_mmio_res) {
> - release_mem_region(hbus->low_mmio_res->start,
> -resource_size(hbus->low_mmio_res));
> + vmbus_free_mmio(hbus->low_mmio_res->start,
> + resource_size(hbus->low_mmio_res));
>   }
>  
>   return ret;
> @@ -1924,7 +1924,7 @@ static int hv_allocate_config_window(struct 
> hv_pcibus_device *hbus)
>  
>  static void hv_free_config_window(struct hv_pcibus_device *hbus)
>  {
> - release_mem_region(hbus->mem_config->start, PCI_CONFIG_MMIO_LENGTH);
> + vmbus_free_mmio(hbus->mem_config->start, PCI_CONFIG_MMIO_LENGTH);
>  }
>  
>  /**
> diff --git a/drivers/video/fbdev/hyperv_fb.c b/drivers/video/fbdev/hyperv_fb.c
> index e2451bd..2fd49b2 100644
> --- a/drivers/video/fbdev/hyperv_fb.c
> +++ b/drivers/video/fbdev/hyperv_fb.c
> @@ -743,7 +743,7 @@ static int hvfb_getmem(struct hv_device *hdev, struct 
> fb_info *info)
>  err3:
>   iounmap(fb_virt);
>  err2:
> - release_mem_region(par->mem->start, screen_fb_size);
> + vmbus_free_mmio(par->mem->start, screen_fb_size);
>   par->mem = NULL;
>  err1:
>   if (!gen2vm)
> @@ -758,7 +758,7 @@ static void hvfb_putmem(struct fb_info *info)
>   struct hvfb_par *par = info->par;
>  
>   iounmap(info->screen_base);
> - release_mem_region(par->mem->start, screen_fb_size);
> + vmbus_free_mmio(par->mem->start, screen_fb_size);
>   par->mem = NULL;
>  }
>  
> -- 
> 1.9.1
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-pci" in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH] staging: iio: ad7606: use iio_device_{claim|release}_direct_mode()

2016-04-05 Thread Alison Schofield
On Sun, Apr 03, 2016 at 10:09:13AM +0100, Jonathan Cameron wrote:
> On 01/04/16 17:53, Alison Schofield wrote:
> > Two instances are moved to the new claim/release API:
> > 
> > In the first instance, the driver was using mlock followed by
> > iio_buffer_enabled(). Replace that code with the new API to guarantee
> > the device stays in direct mode. There is no change in driver behavior.
> > 
> > In the second instance, the driver was not using mlock to hold the
> > device in direct mode, but should have been.  Here we introduce the
> > new API to guarantee direct mode. This is a change in driver behavior.
> > 
> > Signed-off-by: Alison Schofield 
> > ---
> >  drivers/staging/iio/adc/ad7606_core.c | 15 ---
> >  1 file changed, 8 insertions(+), 7 deletions(-)
> > 
> > diff --git a/drivers/staging/iio/adc/ad7606_core.c 
> > b/drivers/staging/iio/adc/ad7606_core.c
> > index 6dbc811..f914b8d 100644
> > --- a/drivers/staging/iio/adc/ad7606_core.c
> > +++ b/drivers/staging/iio/adc/ad7606_core.c
> > @@ -88,12 +88,12 @@ static int ad7606_read_raw(struct iio_dev *indio_dev,
> >  
> > switch (m) {
> > case IIO_CHAN_INFO_RAW:
> > -   mutex_lock(&indio_dev->mlock);
> > -   if (iio_buffer_enabled(indio_dev))
> > -   ret = -EBUSY;
> > -   else
> > -   ret = ad7606_scan_direct(indio_dev, chan->address);
> > -   mutex_unlock(&indio_dev->mlock);
> > +   ret = iio_device_claim_direct_mode(indio_dev);
> > +   if (ret)
> > +   return ret;
> > +
> > +   ret = ad7606_scan_direct(indio_dev, chan->address);
> > +   iio_device_release_direct_mode(indio_dev);
> >  
> > if (ret < 0)
> > return ret;
> > @@ -411,8 +411,9 @@ static irqreturn_t ad7606_interrupt(int irq, void 
> > *dev_id)
> > struct iio_dev *indio_dev = dev_id;
> > struct ad7606_state *st = iio_priv(indio_dev);
> >  
> > -   if (iio_buffer_enabled(indio_dev)) {
> > +   if (!iio_device_claim_direct_mode(indio_dev))  {
> > schedule_work(&st->poll_work);
> > +   iio_device_release_direct_mode(indio_dev);
> Unfortunately this won't work.  That interrupt is still in traditional non
> threaded form.  This will take a mutex in a top half interrupt handler
> where a sleep cannot occur.
> 
> I'm just wondering how expensive it would be to fix this by moving that over
> to a threaded handler.  In the poll_work case (buffer) it would be cleaner to 
> do
> so. I'm really confused what the intended interrupt handler
> is in here.  I 'think' the sequence is:
> 
> Trigger fires the convst pin whether in top half or the bottom half of
> a threaded interrupt, but not both - I guess this works, if it is rather
> 'unusual'.
> 
> We then get a interrupt to indicate that it has finished conversion and that
> filters through to actually fill the buffer via a traditional top half /
> bottom half interrupt handler.
> 
> So if we were to convert that to a threaded interrupt (with no top half / non
> threaded part), we could drop the schedule_work and just call
> ad7606_poll_bh_to_ring from the thread handler.
> 
> In the direct read case I doubt we care about the delay in dropping to a
> thread prior to signalling the data is ready.
> 
> Can't think why this driver is still in staging :)
> 
> Lars, any interest from Analog in getting this one cleaned up?  Also
> do you have any test hardware, if we mess around with this interrupt handling?
> 
> Jonathan

I see the problem. Thanks for the review and the details for the
redesign.  Plan to v2 this patch leaving out this piece. I'll keep
the interrupt handler rework on my radar pending Lars's comments.

alisons

> 
> 
> > } else {
> > st->done = true;
> > wake_up_interruptible(&st->wq_data_avail);
> > 
> 
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 1/2] Drivers: hv: balloon: don't crash when memory is added in non-sorted order

2016-04-05 Thread Vitaly Kuznetsov
When we iterate through all HA regions in handle_pg_range() we have an
assumption that all these regions are sorted in the list and the
'start_pfn >= has->end_pfn' check is enough to find the proper region.
Unfortunately it's not the case with WS2016 where host can hot-add regions
in a different order. We end up modifying the wrong HA region and crashing
later on pages online. Modify the check to make sure we found the region
we were searching for while iterating. Fix the same check in pfn_covered()
as well.

Signed-off-by: Vitaly Kuznetsov 
---
 drivers/hv/hv_balloon.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/hv/hv_balloon.c b/drivers/hv/hv_balloon.c
index b853b4b..43af913 100644
--- a/drivers/hv/hv_balloon.c
+++ b/drivers/hv/hv_balloon.c
@@ -714,7 +714,7 @@ static bool pfn_covered(unsigned long start_pfn, unsigned 
long pfn_cnt)
 * If the pfn range we are dealing with is not in the current
 * "hot add block", move on.
 */
-   if ((start_pfn >= has->end_pfn))
+   if (start_pfn < has->start_pfn || start_pfn >= has->end_pfn)
continue;
/*
 * If the current hot add-request extends beyond
@@ -768,7 +768,7 @@ static unsigned long handle_pg_range(unsigned long pg_start,
 * If the pfn range we are dealing with is not in the current
 * "hot add block", move on.
 */
-   if ((start_pfn >= has->end_pfn))
+   if (start_pfn < has->start_pfn || start_pfn >= has->end_pfn)
continue;
 
old_covered_state = has->covered_end_pfn;
-- 
2.5.5

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 0/2] Drivers: hv: balloon: two memory hotplug fixes

2016-04-05 Thread Vitaly Kuznetsov
Hi,

I found an issue (crash) while testing memory hotplug on WS2016TP4 host.
It should be easily reproducible with the following test sequence
 (4.6-rc2):

1) Start a VM with 4 vCPUs in 4 NUMA nodes, 4096Mb of RAM.
2) Enable memory auto onlining with 
   'echo online > /sys/devices/system/memory/auto_online_blocks'
3) Wait till hv_balloon driver finishes negotiation.
4) Increase memory to 8192Mb.
5) Increase memory to 1Mb.

The first patch in the series fixes the issue. While writing it I stumbled
upon an unrelated issue which I fix with PATCH 2.

Please review.

Vitaly Kuznetsov (2):
  Drivers: hv: balloon: don't crash when memory is added in non-sorted
order
  Drivers: hv: balloon: reset host_specified_ha_region

 drivers/hv/hv_balloon.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

-- 
2.5.5

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 2/2] Drivers: hv: balloon: reset host_specified_ha_region

2016-04-05 Thread Vitaly Kuznetsov
We set host_specified_ha_region = true on certain request but this is a
global state which stays 'true' forever. We need to reset it when we
receive a request where ha_region is not specified. I did not see any
real issues, the bug was found by code inspection.

Signed-off-by: Vitaly Kuznetsov 
---
 drivers/hv/hv_balloon.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/hv/hv_balloon.c b/drivers/hv/hv_balloon.c
index 43af913..df35fb7 100644
--- a/drivers/hv/hv_balloon.c
+++ b/drivers/hv/hv_balloon.c
@@ -1400,6 +1400,7 @@ static void balloon_onchannelcallback(void *context)
 * This is a normal hot-add request specifying
 * hot-add memory.
 */
+   dm->host_specified_ha_region = false;
ha_pg_range = &ha_msg->range;
dm->ha_wrk.ha_page_range = *ha_pg_range;
dm->ha_wrk.ha_region_range.page_range = 0;
-- 
2.5.5

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 1/1] Drivers: hv: vmbus: Fix signaling logic in hv_need_to_signal_on_read()

2016-04-05 Thread K. Y. Srinivasan
On the consumer side, we have interrupt driven flow management of the
producer. It is sufficient to base the signaling decision on the
amount of space that is available to write after the read is complete.
The current code samples the previous available space and uses this
in making the signaling decision. This state can be stale and is
unnecessary. Since the state can be stale, we end up not signaling
the host (when we should) and this can result in a hang. Fix this
problem by removing the unnecessary check. I would like to thank
Arseney Romanenko  for pointing out this issue.

Also, issue a full memory barrier before making the signaling descision
to correctly deal with potential reordering of the write (read index)
followed by the read of pending_sz.

Signed-off-by: K. Y. Srinivasan 
Tested-by: Dexuan Cui 
Cc: 
---
 drivers/hv/ring_buffer.c |   26 --
 1 files changed, 20 insertions(+), 6 deletions(-)

diff --git a/drivers/hv/ring_buffer.c b/drivers/hv/ring_buffer.c
index 5613e2b..a40a73a 100644
--- a/drivers/hv/ring_buffer.c
+++ b/drivers/hv/ring_buffer.c
@@ -103,15 +103,29 @@ static bool hv_need_to_signal(u32 old_write, struct 
hv_ring_buffer_info *rbi)
  *there is room for the producer to send the pending packet.
  */
 
-static bool hv_need_to_signal_on_read(u32 prev_write_sz,
- struct hv_ring_buffer_info *rbi)
+static bool hv_need_to_signal_on_read(struct hv_ring_buffer_info *rbi)
 {
u32 cur_write_sz;
u32 r_size;
-   u32 write_loc = rbi->ring_buffer->write_index;
+   u32 write_loc;
u32 read_loc = rbi->ring_buffer->read_index;
-   u32 pending_sz = rbi->ring_buffer->pending_send_sz;
+   u32 pending_sz;
 
+   /*
+* Issue a full memory barrier before making the signaling decision.
+* Here is the reason for having this barrier:
+* If the reading of the pend_sz (in this function)
+* were to be reordered and read before we commit the new read
+* index (in the calling function)  we could
+* have a problem. If the host were to set the pending_sz after we
+* have sampled pending_sz and go to sleep before we commit the
+* read index, we could miss sending the interrupt. Issue a full
+* memory barrier to address this.
+*/
+   mb();
+
+   pending_sz = rbi->ring_buffer->pending_send_sz;
+   write_loc = rbi->ring_buffer->write_index;
/* If the other end is not blocked on write don't bother. */
if (pending_sz == 0)
return false;
@@ -120,7 +134,7 @@ static bool hv_need_to_signal_on_read(u32 prev_write_sz,
cur_write_sz = write_loc >= read_loc ? r_size - (write_loc - read_loc) :
read_loc - write_loc;
 
-   if ((prev_write_sz < pending_sz) && (cur_write_sz >= pending_sz))
+   if (cur_write_sz >= pending_sz)
return true;
 
return false;
@@ -455,7 +469,7 @@ int hv_ringbuffer_read(struct hv_ring_buffer_info 
*inring_info,
/* Update the read index */
hv_set_next_read_location(inring_info, next_read_location);
 
-   *signal = hv_need_to_signal_on_read(bytes_avail_towrite, inring_info);
+   *signal = hv_need_to_signal_on_read(inring_info);
 
return ret;
 }
-- 
1.7.4.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH] staging: rts5208: ensure braces on all arms of if stmt

2016-04-05 Thread Nicholas Sim
Added braces on if arm of if statement where else arm already needs
braces as suggested for clarity in Documentation/CodingStyle (several)

Signed-off-by: Nicholas Sim 
---
 drivers/staging/rts5208/sd.c | 16 
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/staging/rts5208/sd.c b/drivers/staging/rts5208/sd.c
index 87d6976..6219e04 100644
--- a/drivers/staging/rts5208/sd.c
+++ b/drivers/staging/rts5208/sd.c
@@ -1928,9 +1928,9 @@ static int sd_tuning_rx(struct rtsx_chip *chip)
tuning_cmd = sd_sdr_tuning_rx_cmd;
 
} else {
-   if (CHK_MMC_DDR52(sd_card))
+   if (CHK_MMC_DDR52(sd_card)) {
tuning_cmd = mmc_ddr_tunning_rx_cmd;
-   else {
+   } else {
rtsx_trace(chip);
return STATUS_FAIL;
}
@@ -2054,9 +2054,9 @@ static int sd_tuning_tx(struct rtsx_chip *chip)
tuning_cmd = sd_sdr_tuning_tx_cmd;
 
} else {
-   if (CHK_MMC_DDR52(sd_card))
+   if (CHK_MMC_DDR52(sd_card)) {
tuning_cmd = sd_ddr_tuning_tx_cmd;
-   else {
+   } else {
rtsx_trace(chip);
return STATUS_FAIL;
}
@@ -2678,9 +2678,9 @@ RTY_SD_RST:
}
 
j++;
-   if (j < 3)
+   if (j < 3) {
goto RTY_SD_RST;
-   else {
+   } else {
rtsx_trace(chip);
return STATUS_FAIL;
}
@@ -2690,9 +2690,9 @@ RTY_SD_RST:
SD_RSP_TYPE_R3, rsp, 5);
if (retval != STATUS_SUCCESS) {
k++;
-   if (k < 3)
+   if (k < 3) {
goto RTY_SD_RST;
-   else {
+   } else {
rtsx_trace(chip);
return STATUS_FAIL;
}
-- 
2.4.3

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH] staging: wlan-ng: rewrite NULL comparison

2016-04-05 Thread Nicholas Sim
It is not necessary to compare explicitly to NULL. Rewrite if condition
as (!dev) or (dev) as suggested in Documentation/CodingStyle

Signed-off-by: Nicholas Sim 
---
 drivers/staging/wlan-ng/hfa384x_usb.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/staging/wlan-ng/hfa384x_usb.c 
b/drivers/staging/wlan-ng/hfa384x_usb.c
index 21a92df..3378107 100644
--- a/drivers/staging/wlan-ng/hfa384x_usb.c
+++ b/drivers/staging/wlan-ng/hfa384x_usb.c
@@ -614,7 +614,7 @@ static hfa384x_usbctlx_t *usbctlx_alloc(void)
 
ctlx = kzalloc(sizeof(*ctlx),
   in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
-   if (ctlx != NULL)
+   if (ctlx)
init_completion(&ctlx->done);
 
return ctlx;
@@ -797,7 +797,7 @@ static inline struct usbctlx_completor *init_rmem_completor(
 */
 static void hfa384x_cb_status(hfa384x_t *hw, const hfa384x_usbctlx_t *ctlx)
 {
-   if (ctlx->usercb != NULL) {
+   if (ctlx->usercb) {
hfa384x_cmdresult_t cmdresult;
 
if (ctlx->state != CTLX_COMPLETE) {
@@ -2738,7 +2738,7 @@ static void hfa384x_usbctlx_completion_task(unsigned long 
data)
/* Call the completion function that this
 * command was assigned, assuming it has one.
 */
-   if (ctlx->cmdcb != NULL) {
+   if (ctlx->cmdcb) {
spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
ctlx->cmdcb(hw, ctlx);
spin_lock_irqsave(&hw->ctlxq.lock, flags);
@@ -3629,7 +3629,7 @@ static void hfa384x_ctlxout_callback(struct urb *urb)
dbprint_urb(urb);
 #endif
if ((urb->status == -ESHUTDOWN) ||
-   (urb->status == -ENODEV) || (hw == NULL))
+   (urb->status == -ENODEV) || !hw)
return;
 
 retry:
-- 
2.4.3

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH] staging: rts5208: ensure braces on all arms of if stmt

2016-04-05 Thread Nicholas Sim
Added braces on if arm of if statement where else arm already needs braces
as suggested for clarity in Documentation/CodingStyle

Signed-off-by: Nicholas Sim 
---
 drivers/staging/rts5208/ms.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/staging/rts5208/ms.c b/drivers/staging/rts5208/ms.c
index 3e75db7..2ad4ea0 100644
--- a/drivers/staging/rts5208/ms.c
+++ b/drivers/staging/rts5208/ms.c
@@ -794,8 +794,9 @@ static int ms_confirm_cpu_startup(struct rtsx_chip *chip)
}
 
if (val & INT_REG_ERR) {
-   if (val & INT_REG_CMDNK)
+   if (val & INT_REG_CMDNK) {
chip->card_wp |= (MS_CARD);
+   }
else {
rtsx_trace(chip);
return STATUS_FAIL;
-- 
2.4.3

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH] staging: rtl8192u: rewrite NULL comparison for pointers

2016-04-05 Thread Nicholas Sim
When testing pointers, it is not necessary to explicitly compare to
NULL. Rewrite if condition as (!ptr) or (ptr) as suggested in
Documentation/CodingStyle

Signed-off-by: Nicholas Sim 
---
 drivers/staging/rtl8192u/r8192U_core.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/staging/rtl8192u/r8192U_core.c 
b/drivers/staging/rtl8192u/r8192U_core.c
index 9b319b3..dba52741 100644
--- a/drivers/staging/rtl8192u/r8192U_core.c
+++ b/drivers/staging/rtl8192u/r8192U_core.c
@@ -1994,7 +1994,7 @@ static int rtl8192_qos_association_resp(struct r8192_priv 
*priv,
u32 size = sizeof(struct ieee80211_qos_parameters);
int set_qos_param = 0;
 
-   if ((priv == NULL) || (network == NULL))
+   if (!priv || !network)
return 0;
 
if (priv->ieee80211->state != IEEE80211_LINKED)
@@ -4938,7 +4938,7 @@ static int rtl8192_usb_probe(struct usb_interface *intf,
RT_TRACE(COMP_INIT, "Oops: i'm coming\n");
 
dev = alloc_ieee80211(sizeof(struct r8192_priv));
-   if (dev == NULL)
+   if (!dev)
return -ENOMEM;
 
usb_set_intfdata(intf, dev);
@@ -5157,7 +5157,7 @@ void setKey(struct net_device *dev, u8 EntryNo, u8 
KeyIndex, u16 KeyType,
write_nic_dword(dev, RWCAM, TargetCommand);
} else {
/* Key Material */
-   if (KeyContent != NULL) {
+   if (KeyContent) {
write_nic_dword(dev, WCAMI, (u32)(*(KeyContent 
+ i - 2)));
write_nic_dword(dev, RWCAM, TargetCommand);
}
-- 
2.4.3

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH] staging: rtl8192u: add blank line after declarations

2016-04-05 Thread Nicholas Sim
Add a blank line after function/struct/union/enum declarations for
readability, as suggested in Documentation/CodingStyle

Signed-off-by: Nicholas Sim 
---
 drivers/staging/rtl8192u/r8192U_core.c | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/drivers/staging/rtl8192u/r8192U_core.c 
b/drivers/staging/rtl8192u/r8192U_core.c
index 21d5693..9b319b3 100644
--- a/drivers/staging/rtl8192u/r8192U_core.c
+++ b/drivers/staging/rtl8192u/r8192U_core.c
@@ -297,6 +297,7 @@ int read_nic_byte_E(struct net_device *dev, int indx, u8 
*data)
 
return 0;
 }
+
 /* as 92U has extend page from 4 to 16, so modify functions below. */
 void write_nic_byte(struct net_device *dev, int indx, u8 data)
 {
@@ -768,6 +769,7 @@ static u32 get_rxpacket_shiftbytes_819xusb(struct 
ieee80211_rx_stats *pstats)
return (sizeof(rx_desc_819x_usb) + pstats->RxDrvInfoSize
+ pstats->RxBufShift);
 }
+
 static int rtl8192_rx_initiate(struct net_device *dev)
 {
struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
@@ -864,6 +866,7 @@ void rtl8192_set_rxconf(struct net_device *dev)
 
write_nic_dword(dev, RCR, rxconf);
 }
+
 /* wait to be removed */
 void rtl8192_rx_enable(struct net_device *dev)
 {
@@ -935,6 +938,7 @@ inline u16 ieeerate2rtlrate(int rate)
return 3;
}
 }
+
 static u16 rtl_rate[] = {10, 20, 55, 110, 60, 90, 120, 180, 240, 360, 480, 
540};
 inline u16 rtl8192_rate2rate(short rate)
 {
@@ -1261,6 +1265,7 @@ static void rtl8192_update_cap(struct net_device *dev, 
u16 cap)
write_nic_byte(dev, SLOT_TIME, slot_time);
}
 }
+
 static void rtl8192_net_update(struct net_device *dev)
 {
struct r8192_priv *priv = ieee80211_priv(dev);
@@ -1298,6 +1303,7 @@ void rtl819xusb_beacon_tx(struct net_device *dev, u16  
tx_rate)
 {
 
 }
+
 inline u8 rtl8192_IsWirelessBMode(u16 rate)
 {
if (((rate <= 110) && (rate != 60) && (rate != 90)) || (rate == 220))
@@ -1765,6 +1771,7 @@ static short rtl8192_usb_initendpoints(struct net_device 
*dev)
netdev_dbg(dev, "End of initendpoints\n");
return 0;
 }
+
 #ifdef THOMAS_BEACON
 static void rtl8192_usb_deleteendpoints(struct net_device *dev)
 {
@@ -1868,6 +1875,7 @@ static void rtl8192_update_beacon(struct work_struct 
*work)
net->bssht.bdRT2RTLongSlotTime;
rtl8192_update_cap(dev, net->capability);
 }
+
 /*
 * background support to run QoS activate functionality
 */
@@ -2161,6 +2169,7 @@ static u8 rtl8192_getSupportedWireleeMode(struct 
net_device *dev)
}
return ret;
 }
+
 static void rtl8192_SetWirelessMode(struct net_device *dev, u8 wireless_mode)
 {
struct r8192_priv *priv = ieee80211_priv(dev);
@@ -2203,6 +2212,7 @@ static void rtl8192_SetWirelessMode(struct net_device 
*dev, u8 wireless_mode)
RT_TRACE(COMP_INIT, "Current Wireless Mode is %x\n", wireless_mode);
rtl8192_refresh_supportrate(priv);
 }
+
 /* init priv variables here. only non_zero value should be initialized here. */
 static void rtl8192_init_priv_variable(struct net_device *dev)
 {
@@ -2410,6 +2420,7 @@ static inline u16 endian_swap(u16 *data)
*data = (tmp >> 8) | (tmp << 8);
return *data;
 }
+
 static void rtl8192_read_eeprom_info(struct net_device *dev)
 {
u16 wEPROM_ID = 0;
@@ -3268,6 +3279,7 @@ static void CamRestoreAllEntry(struct net_device *dev)
   CAM_CONST_ADDR[0], 0, NULL);
}
 }
+
 /* This function is used to fix Tx/Rx stop bug temporarily.
  * This function will do "system reset" to NIC when Tx or Rx is stuck.
  * The method checking Tx/Rx stuck of this function is supported by FW,
@@ -3485,6 +3497,7 @@ static void watch_dog_timer_callback(unsigned long data)
mod_timer(&priv->watch_dog_timer,
  jiffies + msecs_to_jiffies(IEEE80211_WATCH_DOG_TIME));
 }
+
 static int _rtl8192_up(struct net_device *dev)
 {
struct r8192_priv *priv = ieee80211_priv(dev);
@@ -4159,6 +4172,7 @@ static u8 rtl819x_evm_dbtopercentage(char value)
ret_val = 100;
return ret_val;
 }
+
 /* We want good-looking for signal strength/quality */
 static long rtl819x_signal_scale_mapping(long currsig)
 {
-- 
2.4.3

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH] staging: rtl8192u: remove blank lines after braces (opening)

2016-04-05 Thread Nicholas Sim
Remove unneeded blank lines appearing after opening braces as suggested
by checkpatch.pl

Signed-off-by: Nicholas Sim 
---
 drivers/staging/rtl8192u/r8192U_core.c | 14 --
 1 file changed, 14 deletions(-)

diff --git a/drivers/staging/rtl8192u/r8192U_core.c 
b/drivers/staging/rtl8192u/r8192U_core.c
index 2f506b8..21d5693 100644
--- a/drivers/staging/rtl8192u/r8192U_core.c
+++ b/drivers/staging/rtl8192u/r8192U_core.c
@@ -323,7 +323,6 @@ void write_nic_byte(struct net_device *dev, int indx, u8 
data)
 
 void write_nic_word(struct net_device *dev, int indx, u16 data)
 {
-
int status;
 
struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
@@ -347,7 +346,6 @@ void write_nic_word(struct net_device *dev, int indx, u16 
data)
 
 void write_nic_dword(struct net_device *dev, int indx, u32 data)
 {
-
int status;
 
struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
@@ -733,7 +731,6 @@ void rtl8192_update_msr(struct net_device *dev)
 * master (see the create BSS/IBSS func)
 */
if (priv->ieee80211->state == IEEE80211_LINKED) {
-
if (priv->ieee80211->iw_mode == IW_MODE_INFRA)
msr |= (MSR_LINK_MANAGED << MSR_LINK_SHIFT);
else if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
@@ -768,7 +765,6 @@ static void rtl8192_rx_isr(struct urb *urb);
 
 static u32 get_rxpacket_shiftbytes_819xusb(struct ieee80211_rx_stats *pstats)
 {
-
return (sizeof(rx_desc_819x_usb) + pstats->RxDrvInfoSize
+ pstats->RxBufShift);
 }
@@ -1267,7 +1263,6 @@ static void rtl8192_update_cap(struct net_device *dev, 
u16 cap)
 }
 static void rtl8192_net_update(struct net_device *dev)
 {
-
struct r8192_priv *priv = ieee80211_priv(dev);
struct ieee80211_network *net;
u16 BcnTimeCfg = 0, BcnCW = 6, BcnIFS = 0xf;
@@ -1725,7 +1720,6 @@ static short rtl8192_usb_initendpoints(struct net_device 
*dev)
 
 #ifndef JACKSON_NEW_RX
for (i = 0; i < (MAX_RX_URB + 1); i++) {
-
priv->rx_urb[i] = usb_alloc_urb(0, GFP_KERNEL);
 
priv->rx_urb[i]->transfer_buffer =
@@ -2658,7 +2652,6 @@ static short rtl8192_get_channel_map(struct net_device 
*dev)
 
 static short rtl8192_init(struct net_device *dev)
 {
-
struct r8192_priv *priv = ieee80211_priv(dev);
 
memset(&(priv->stats), 0, sizeof(struct Stats));
@@ -3007,7 +3000,6 @@ static bool rtl8192_adapter_start(struct net_device *dev)
 bMaskByte2);
 
for (i = 0; i < CCKTxBBGainTableLength; i++) {
-
if (TempCCk == 
priv->cck_txbbgain_table[i].ccktxbb_valuearray[0]) {

priv->cck_present_attentuation_20Mdefault = (u8)i;
break;
@@ -3228,7 +3220,6 @@ static void CamRestoreAllEntry(struct net_device *dev)
 
if ((priv->ieee80211->pairwise_key_type == KEY_TYPE_WEP40) ||
(priv->ieee80211->pairwise_key_type == KEY_TYPE_WEP104)) {
-
for (EntryId = 0; EntryId < 4; EntryId++) {
MacAddr = CAM_CONST_ADDR[EntryId];
setKey(dev, EntryId, EntryId,
@@ -3237,7 +3228,6 @@ static void CamRestoreAllEntry(struct net_device *dev)
}
 
} else if (priv->ieee80211->pairwise_key_type == KEY_TYPE_TKIP) {
-
if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
setKey(dev, 4, 0, priv->ieee80211->pairwise_key_type,
   (u8 *)dev->dev_addr, 0, NULL);
@@ -3245,7 +3235,6 @@ static void CamRestoreAllEntry(struct net_device *dev)
setKey(dev, 4, 0, priv->ieee80211->pairwise_key_type,
   MacAddr, 0, NULL);
} else if (priv->ieee80211->pairwise_key_type == KEY_TYPE_CCMP) {
-
if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
setKey(dev, 4, 0, priv->ieee80211->pairwise_key_type,
   (u8 *)dev->dev_addr, 0, NULL);
@@ -3446,7 +3435,6 @@ static void rtl819x_watchdog_wqcallback(struct 
work_struct *work)
/* for AP roaming */
if (priv->ieee80211->state == IEEE80211_LINKED &&
priv->ieee80211->iw_mode == IW_MODE_INFRA) {
-
rtl819x_update_rxcounts(priv, &TotalRxBcnNum, &TotalRxDataNum);
if ((TotalRxBcnNum + TotalRxDataNum) == 0) {
 #ifdef TODO
@@ -4865,7 +4853,6 @@ static void rtl8192_rx_cmd(struct sk_buff *skb)
};
 
if ((skb->len >= (20 + sizeof(rx_desc_819x_usb))) && (skb->len < 
RX_URB_SIZE)) {
-
query_rx_cmdpkt_desc_status(skb, &stats);
/* prfd->queue_id = 1; */
 
@@ -5000,7 +4987,6 @@ fail:
  */
 static void rtl8192_cancel_deferred_work(struct r8192_priv *priv)
 {
-
cancel_work_sync(&priv->reset_wq);
cancel_delayed_work(&priv->watch_dog_wq

Re: Staging: unisys/verisonic: Correct double unlock

2016-04-05 Thread Neil Horman
On Tue, Apr 05, 2016 at 03:49:57PM +, Sell, Timothy C wrote:
> > -Original Message-
> > From: Neil Horman [mailto:nhor...@redhat.com]
> > Sent: Tuesday, April 05, 2016 10:58 AM
> > To: Sell, Timothy C
> > Cc: Iban Rodriguez; Kershner, David A; Greg Kroah-Hartman; Benjamin
> > Romer; *S-Par-Maintainer; de...@driverdev.osuosl.org; linux-
> > ker...@vger.kernel.org
> > Subject: Re: Staging: unisys/verisonic: Correct double unlock
> > 
> > On Mon, Apr 04, 2016 at 09:40:13PM +, Sell, Timothy C wrote:
> > > > -Original Message-
> > > > From: Neil Horman [mailto:nhor...@redhat.com]
> > > > Sent: Monday, April 04, 2016 10:35 AM
> > > > To: Sell, Timothy C
> > > > Cc: Iban Rodriguez; Kershner, David A; Greg Kroah-Hartman; Benjamin
> > > > Romer; *S-Par-Maintainer; de...@driverdev.osuosl.org; linux-
> > > > ker...@vger.kernel.org
> > > > Subject: Re: Staging: unisys/verisonic: Correct double unlock
> > > >
> > > > On Sat, Apr 02, 2016 at 11:20:14PM +, Sell, Timothy C wrote:
> > > > > > -Original Message-
> > > > > > From: Iban Rodriguez [mailto:iban.rodrig...@ono.com]
> > > > > > Sent: Saturday, April 02, 2016 1:47 PM
> > > > > > To: Kershner, David A; Greg Kroah-Hartman; Benjamin Romer; Sell,
> > > > Timothy
> > > > > > C; Neil Horman
> > > > > > Cc: *S-Par-Maintainer; de...@driverdev.osuosl.org; linux-
> > > > > > ker...@vger.kernel.org; Iban Rodriguez
> > > > > > Subject: Staging: unisys/verisonic: Correct double unlock
> > > > > >
> > > > > > 'priv_lock' is unlocked twice. The first one is removed and
> > > > > > the function 'visornic_serverdown_complete' is now called with
> > > > > > 'priv_lock' locked because 'devdata' is modified inside.
> > > > > >
> > > > > > Signed-off-by: Iban Rodriguez 
> > > > > > ---
> > > > > >  drivers/staging/unisys/visornic/visornic_main.c | 1 -
> > > > > >  1 file changed, 1 deletion(-)
> > > > > >
> > > > > > diff --git a/drivers/staging/unisys/visornic/visornic_main.c
> > > > > > b/drivers/staging/unisys/visornic/visornic_main.c
> > > > > > index be0d057346c3..af03f2938fe9 100644
> > > > > > --- a/drivers/staging/unisys/visornic/visornic_main.c
> > > > > > +++ b/drivers/staging/unisys/visornic/visornic_main.c
> > > > > > @@ -368,7 +368,6 @@ visornic_serverdown(struct visornic_devdata
> > > > > > *devdata,
> > > > > > }
> > > > > > devdata->server_change_state = true;
> > > > > > devdata->server_down_complete_func = complete_func;
> > > > > > -   spin_unlock_irqrestore(&devdata->priv_lock, flags);
> > > > > > visornic_serverdown_complete(devdata);
> > > > > > } else if (devdata->server_change_state) {
> > > > > > dev_dbg(&devdata->dev->device, "%s changing state\n",
> > > > >
> > > > > I agree there is a bug here involving priv_lock being unlocked
> > > > > twice, but this patch isn't the appropriate fix.  Reason is, we can 
> > > > > NOT
> > > > > call visornic_serverdown_complete() while holding a spinlock
> > > > > (which is what this patch would cause to occur) because
> > > > > visornic_serverdown_complete() might block when it calls
> > > > > rtnl_lock() in this code sequence (rtnl_lock() grabs a mutex):
> > > > >
> > > > > rtnl_lock();
> > > > > dev_close(netdev);
> > > > > rtnl_unlock();
> > > > >
> > > > > Blocking with a spinlock held is always a bad idea.  :-(
> > > > >
> > > >
> > > > You should just get rid of the priv_lock entirely, its not needed.
> > > >
> > > > priv_lock is used the following functions:
> > > >
> > > > visornic_serverdown - only called at the end of a tx_timeout reset
> > > > operation, so
> > > > you are sure that the rx and tx paths are quiesced (i.e. no data access
> > > > happening)
> > > >
> > > > visornic_disable_with_timeout - move the netif_stop_queue operation
> > to
> > > > the top
> > > > of this function and you will be guaranteed no concurrent access in the 
> > > > tx
> > > > path
> > > >
> > > > visornic_enable_with_timeout - same as above, make sure that
> > > > netif_start_queue
> > > > and napi_enable are at the end of the function and you are guarantted
> > no
> > > > concurrent access.
> > > >
> > > > visornic_xmit - The queue lock in the netdev_start_xmit routine
> > guarantees
> > > > you
> > > > single access here from multiple transmits.
> > > >
> > > > visornic_xmit_timeout - only called on a tx timeout, when you are
> > > > guaranteed not
> > > > to have concurrent transmit occuing, by definition.
> > > >
> > > > visornic_rx - the only tests made here are to devdata members that are
> > > > altered
> > > > in service_resp_queue, and the visornic_rx is only called from
> > > > service_resp_queue, so you are guaranteed a stable data structure, as
> > there
> > > > is
> > > > only ever one context in service_resp_queue as its called from the napi
> > poll
> > > > routine
> > > >
> > > > service_resp_queue - Same as above, for any given queue,
> > > > service_resp_queue only
> > > > has one context exectu

[PATCH] staging: rtl8192u: remove blank lines before braces (closing)

2016-04-05 Thread Nicholas Sim
Remove unneeded blank lines occuring before closing braces

Signed-off-by: Nicholas Sim 
---
 drivers/staging/rtl8192u/r8192U_core.c | 35 --
 1 file changed, 35 deletions(-)

diff --git a/drivers/staging/rtl8192u/r8192U_core.c 
b/drivers/staging/rtl8192u/r8192U_core.c
index 849a95e..2f506b8 100644
--- a/drivers/staging/rtl8192u/r8192U_core.c
+++ b/drivers/staging/rtl8192u/r8192U_core.c
@@ -235,7 +235,6 @@ static void CamResetAllEntry(struct net_device *dev)
 */
ulcommand |= BIT(31) | BIT(30);
write_nic_dword(dev, RWCAM, ulcommand);
-
 }
 
 
@@ -319,8 +318,6 @@ void write_nic_byte(struct net_device *dev, int indx, u8 
data)
 
if (status < 0)
netdev_err(dev, "write_nic_byte TimeOut! status: %d\n", status);
-
-
 }
 
 
@@ -345,7 +342,6 @@ void write_nic_word(struct net_device *dev, int indx, u16 
data)
 
if (status < 0)
netdev_err(dev, "write_nic_word TimeOut! status: %d\n", status);
-
 }
 
 
@@ -372,7 +368,6 @@ void write_nic_dword(struct net_device *dev, int indx, u32 
data)
if (status < 0)
netdev_err(dev, "write_nic_dword TimeOut! status: %d\n",
   status);
-
 }
 
 
@@ -776,7 +771,6 @@ static u32 get_rxpacket_shiftbytes_819xusb(struct 
ieee80211_rx_stats *pstats)
 
return (sizeof(rx_desc_819x_usb) + pstats->RxDrvInfoSize
+ pstats->RxBufShift);
-
 }
 static int rtl8192_rx_initiate(struct net_device *dev)
 {
@@ -943,7 +937,6 @@ inline u16 ieeerate2rtlrate(int rate)
return 11;
default:
return 3;
-
}
 }
 static u16 rtl_rate[] = {10, 20, 55, 110, 60, 90, 120, 180, 240, 360, 480, 
540};
@@ -1149,7 +1142,6 @@ static void rtl8192_tx_isr(struct urb *tx_urb)
return; /* avoid further processing AMSDU */
}
}
-
 }
 
 static void rtl8192_config_rate(struct net_device *dev, u16 *rate_config)
@@ -1272,7 +1264,6 @@ static void rtl8192_update_cap(struct net_device *dev, 
u16 cap)
priv->slot_time = slot_time;
write_nic_byte(dev, SLOT_TIME, slot_time);
}
-
 }
 static void rtl8192_net_update(struct net_device *dev)
 {
@@ -1303,9 +1294,6 @@ static void rtl8192_net_update(struct net_device *dev)
 
write_nic_word(dev, BCN_TCFG, BcnTimeCfg);
}
-
-
-
 }
 
 /* temporary hw beacon is not used any more.
@@ -1782,7 +1770,6 @@ static short rtl8192_usb_initendpoints(struct net_device 
*dev)
 
netdev_dbg(dev, "End of initendpoints\n");
return 0;
-
 }
 #ifdef THOMAS_BEACON
 static void rtl8192_usb_deleteendpoints(struct net_device *dev)
@@ -1820,7 +1807,6 @@ void rtl8192_usb_deleteendpoints(struct net_device *dev)
}
kfree(priv->rx_urb);
priv->rx_urb = NULL;
-
}
 #else
kfree(priv->rx_urb);
@@ -1992,7 +1978,6 @@ static int rtl8192_handle_beacon(struct net_device *dev,
rtl8192_qos_handle_probe_response(priv, 1, network);
schedule_delayed_work(&priv->update_beacon_wq, 0);
return 0;
-
 }
 
 /*
@@ -2223,7 +2208,6 @@ static void rtl8192_SetWirelessMode(struct net_device 
*dev, u8 wireless_mode)
priv->ieee80211->pHTInfo->bEnableHT = 0;
RT_TRACE(COMP_INIT, "Current Wireless Mode is %x\n", wireless_mode);
rtl8192_refresh_supportrate(priv);
-
 }
 /* init priv variables here. only non_zero value should be initialized here. */
 static void rtl8192_init_priv_variable(struct net_device *dev)
@@ -2627,7 +2611,6 @@ static void rtl8192_read_eeprom_info(struct net_device 
*dev)
default:
priv->CustomerID = RT_CID_DEFAULT;
break;
-
}
 
switch (priv->CustomerID) {
@@ -2642,7 +2625,6 @@ static void rtl8192_read_eeprom_info(struct net_device 
*dev)
default:
priv->LedStrategy = SW_LED_MODE0;
break;
-
}
 
 
@@ -2797,8 +2779,6 @@ static void rtl8192_hwconfig(struct net_device *dev)
/* Set Tx Antenna including Feedback control */
 
/* Set Auto Rate fallback control */
-
-
 }
 
 
@@ -3037,7 +3017,6 @@ static bool rtl8192_adapter_start(struct net_device *dev)
priv->cck_present_attentuation_difference = 0;
priv->cck_present_attentuation =
priv->cck_present_attentuation_20Mdefault;
-
}
}
write_nic_byte(dev, 0x87, 0x0);
@@ -3222,7 +3201,6 @@ static RESET_TYPE rtl819x_ifcheck_resetornot(struct 
net_device *dev)
} else {
return RESET_TYPE_NORESET;
}
-
 }
 
 static void rtl8192_cancel_deferred_work(struct r8192_priv *priv);
@@ -3485,7 +3463,6 @@ static void rtl819x_watchdog_wqcallback(struct 
work_struct *work)
priv->ieee80211->link_change(dev);
queue_work(priv->ieee80211->wq,
  

RE: Staging: unisys/verisonic: Correct double unlock

2016-04-05 Thread Sell, Timothy C
> -Original Message-
> From: Neil Horman [mailto:nhor...@redhat.com]
> Sent: Tuesday, April 05, 2016 10:58 AM
> To: Sell, Timothy C
> Cc: Iban Rodriguez; Kershner, David A; Greg Kroah-Hartman; Benjamin
> Romer; *S-Par-Maintainer; de...@driverdev.osuosl.org; linux-
> ker...@vger.kernel.org
> Subject: Re: Staging: unisys/verisonic: Correct double unlock
> 
> On Mon, Apr 04, 2016 at 09:40:13PM +, Sell, Timothy C wrote:
> > > -Original Message-
> > > From: Neil Horman [mailto:nhor...@redhat.com]
> > > Sent: Monday, April 04, 2016 10:35 AM
> > > To: Sell, Timothy C
> > > Cc: Iban Rodriguez; Kershner, David A; Greg Kroah-Hartman; Benjamin
> > > Romer; *S-Par-Maintainer; de...@driverdev.osuosl.org; linux-
> > > ker...@vger.kernel.org
> > > Subject: Re: Staging: unisys/verisonic: Correct double unlock
> > >
> > > On Sat, Apr 02, 2016 at 11:20:14PM +, Sell, Timothy C wrote:
> > > > > -Original Message-
> > > > > From: Iban Rodriguez [mailto:iban.rodrig...@ono.com]
> > > > > Sent: Saturday, April 02, 2016 1:47 PM
> > > > > To: Kershner, David A; Greg Kroah-Hartman; Benjamin Romer; Sell,
> > > Timothy
> > > > > C; Neil Horman
> > > > > Cc: *S-Par-Maintainer; de...@driverdev.osuosl.org; linux-
> > > > > ker...@vger.kernel.org; Iban Rodriguez
> > > > > Subject: Staging: unisys/verisonic: Correct double unlock
> > > > >
> > > > > 'priv_lock' is unlocked twice. The first one is removed and
> > > > > the function 'visornic_serverdown_complete' is now called with
> > > > > 'priv_lock' locked because 'devdata' is modified inside.
> > > > >
> > > > > Signed-off-by: Iban Rodriguez 
> > > > > ---
> > > > >  drivers/staging/unisys/visornic/visornic_main.c | 1 -
> > > > >  1 file changed, 1 deletion(-)
> > > > >
> > > > > diff --git a/drivers/staging/unisys/visornic/visornic_main.c
> > > > > b/drivers/staging/unisys/visornic/visornic_main.c
> > > > > index be0d057346c3..af03f2938fe9 100644
> > > > > --- a/drivers/staging/unisys/visornic/visornic_main.c
> > > > > +++ b/drivers/staging/unisys/visornic/visornic_main.c
> > > > > @@ -368,7 +368,6 @@ visornic_serverdown(struct visornic_devdata
> > > > > *devdata,
> > > > >   }
> > > > >   devdata->server_change_state = true;
> > > > >   devdata->server_down_complete_func = complete_func;
> > > > > - spin_unlock_irqrestore(&devdata->priv_lock, flags);
> > > > >   visornic_serverdown_complete(devdata);
> > > > >   } else if (devdata->server_change_state) {
> > > > >   dev_dbg(&devdata->dev->device, "%s changing state\n",
> > > >
> > > > I agree there is a bug here involving priv_lock being unlocked
> > > > twice, but this patch isn't the appropriate fix.  Reason is, we can NOT
> > > > call visornic_serverdown_complete() while holding a spinlock
> > > > (which is what this patch would cause to occur) because
> > > > visornic_serverdown_complete() might block when it calls
> > > > rtnl_lock() in this code sequence (rtnl_lock() grabs a mutex):
> > > >
> > > > rtnl_lock();
> > > > dev_close(netdev);
> > > > rtnl_unlock();
> > > >
> > > > Blocking with a spinlock held is always a bad idea.  :-(
> > > >
> > >
> > > You should just get rid of the priv_lock entirely, its not needed.
> > >
> > > priv_lock is used the following functions:
> > >
> > > visornic_serverdown - only called at the end of a tx_timeout reset
> > > operation, so
> > > you are sure that the rx and tx paths are quiesced (i.e. no data access
> > > happening)
> > >
> > > visornic_disable_with_timeout - move the netif_stop_queue operation
> to
> > > the top
> > > of this function and you will be guaranteed no concurrent access in the tx
> > > path
> > >
> > > visornic_enable_with_timeout - same as above, make sure that
> > > netif_start_queue
> > > and napi_enable are at the end of the function and you are guarantted
> no
> > > concurrent access.
> > >
> > > visornic_xmit - The queue lock in the netdev_start_xmit routine
> guarantees
> > > you
> > > single access here from multiple transmits.
> > >
> > > visornic_xmit_timeout - only called on a tx timeout, when you are
> > > guaranteed not
> > > to have concurrent transmit occuing, by definition.
> > >
> > > visornic_rx - the only tests made here are to devdata members that are
> > > altered
> > > in service_resp_queue, and the visornic_rx is only called from
> > > service_resp_queue, so you are guaranteed a stable data structure, as
> there
> > > is
> > > only ever one context in service_resp_queue as its called from the napi
> poll
> > > routine
> > >
> > > service_resp_queue - Same as above, for any given queue,
> > > service_resp_queue only
> > > has one context exectuing at once.
> > >
> > > host_side_disappeared - only called from visornic_remove, when
> implies
> > > that all
> > > associated devices are closed already, guaranteeing single access.
> > >
> > > visornic_remove
> > > visornic_resume - Both of these function only get called when all
> netwo

[PATCH 4/7] drivers:hv: Reverse order of resources in hyperv_mmio

2016-04-05 Thread K. Y. Srinivasan
From: Jake Oshins 

A patch later in this series allocates child nodes
in this resource tree.  For that to work, this tree
needs to be sorted in ascending order.

Signed-off-by: Jake Oshins 
Signed-off-by: K. Y. Srinivasan 
---
Greg, please apply this to the 4.6 tree.

 drivers/hv/vmbus_drv.c |3 +--
 1 files changed, 1 insertions(+), 2 deletions(-)

diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index 60553c1..1ce47d0 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -1049,7 +1049,6 @@ static acpi_status vmbus_walk_resources(struct 
acpi_resource *res, void *ctx)
new_res->end = end;
 
/*
-* Stick ranges from higher in address space at the front of the list.
 * If two ranges are adjacent, merge them.
 */
do {
@@ -1070,7 +1069,7 @@ static acpi_status vmbus_walk_resources(struct 
acpi_resource *res, void *ctx)
break;
}
 
-   if ((*old_res)->end < new_res->start) {
+   if ((*old_res)->start > new_res->end) {
new_res->sibling = *old_res;
if (prev_res)
(*prev_res)->sibling = new_res;
-- 
1.7.4.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 3/7] drivers:hv: Use new vmbus_mmio_free() from client drivers.

2016-04-05 Thread K. Y. Srinivasan
From: Jake Oshins 

This patch modifies all the callers of vmbus_mmio_allocate()
to call vmbus_mmio_free() instead of release_mem_region().

Signed-off-by: Jake Oshins 
Signed-off-by: K. Y. Srinivasan 
---
Greg, please apply this to the 4.6 tree.

 drivers/pci/host/pci-hyperv.c   |   14 +++---
 drivers/video/fbdev/hyperv_fb.c |4 ++--
 2 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/pci/host/pci-hyperv.c b/drivers/pci/host/pci-hyperv.c
index ed651ba..f2559b6 100644
--- a/drivers/pci/host/pci-hyperv.c
+++ b/drivers/pci/host/pci-hyperv.c
@@ -1795,14 +1795,14 @@ static void hv_pci_free_bridge_windows(struct 
hv_pcibus_device *hbus)
 
if (hbus->low_mmio_space && hbus->low_mmio_res) {
hbus->low_mmio_res->flags |= IORESOURCE_BUSY;
-   release_mem_region(hbus->low_mmio_res->start,
-  resource_size(hbus->low_mmio_res));
+   vmbus_free_mmio(hbus->low_mmio_res->start,
+   resource_size(hbus->low_mmio_res));
}
 
if (hbus->high_mmio_space && hbus->high_mmio_res) {
hbus->high_mmio_res->flags |= IORESOURCE_BUSY;
-   release_mem_region(hbus->high_mmio_res->start,
-  resource_size(hbus->high_mmio_res));
+   vmbus_free_mmio(hbus->high_mmio_res->start,
+   resource_size(hbus->high_mmio_res));
}
 }
 
@@ -1880,8 +1880,8 @@ static int hv_pci_allocate_bridge_windows(struct 
hv_pcibus_device *hbus)
 
 release_low_mmio:
if (hbus->low_mmio_res) {
-   release_mem_region(hbus->low_mmio_res->start,
-  resource_size(hbus->low_mmio_res));
+   vmbus_free_mmio(hbus->low_mmio_res->start,
+   resource_size(hbus->low_mmio_res));
}
 
return ret;
@@ -1924,7 +1924,7 @@ static int hv_allocate_config_window(struct 
hv_pcibus_device *hbus)
 
 static void hv_free_config_window(struct hv_pcibus_device *hbus)
 {
-   release_mem_region(hbus->mem_config->start, PCI_CONFIG_MMIO_LENGTH);
+   vmbus_free_mmio(hbus->mem_config->start, PCI_CONFIG_MMIO_LENGTH);
 }
 
 /**
diff --git a/drivers/video/fbdev/hyperv_fb.c b/drivers/video/fbdev/hyperv_fb.c
index e2451bd..2fd49b2 100644
--- a/drivers/video/fbdev/hyperv_fb.c
+++ b/drivers/video/fbdev/hyperv_fb.c
@@ -743,7 +743,7 @@ static int hvfb_getmem(struct hv_device *hdev, struct 
fb_info *info)
 err3:
iounmap(fb_virt);
 err2:
-   release_mem_region(par->mem->start, screen_fb_size);
+   vmbus_free_mmio(par->mem->start, screen_fb_size);
par->mem = NULL;
 err1:
if (!gen2vm)
@@ -758,7 +758,7 @@ static void hvfb_putmem(struct fb_info *info)
struct hvfb_par *par = info->par;
 
iounmap(info->screen_base);
-   release_mem_region(par->mem->start, screen_fb_size);
+   vmbus_free_mmio(par->mem->start, screen_fb_size);
par->mem = NULL;
 }
 
-- 
1.7.4.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 5/7] drivers:hv: Track allocations of children of hv_vmbus in private resource tree

2016-04-05 Thread K. Y. Srinivasan
From: Jake Oshins 

This patch changes vmbus_allocate_mmio() and vmbus_free_mmio() so
that when child paravirtual devices allocate memory-mapped I/O
space, they allocate it privately from a resource tree pointed
at by hyperv_mmio and also by the public resource tree
iomem_resource.  This allows the region to be marked as "busy"
in the private tree, but a "bridge window" in the public tree,
guaranteeing that no two bridge windows will overlap each other
but while also allowing the PCI device children of the bridge
windows to overlap that window.

One might conclude that this belongs in the pnp layer, rather
than in this driver.  Rafael Wysocki, the maintainter of the
pnp layer, has previously asked that we not modify the pnp layer
as it is considered deprecated.  This patch is thus essentially
a workaround.

Signed-off-by: Jake Oshins 
Signed-off-by: K. Y. Srinivasan 
---
Greg, please apply this to the 4.6 tree.

 drivers/hv/vmbus_drv.c |   22 +-
 1 files changed, 21 insertions(+), 1 deletions(-)

diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index 1ce47d0..dfc6149 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -1128,7 +1128,7 @@ int vmbus_allocate_mmio(struct resource **new, struct 
hv_device *device_obj,
resource_size_t size, resource_size_t align,
bool fb_overlap_ok)
 {
-   struct resource *iter;
+   struct resource *iter, *shadow;
resource_size_t range_min, range_max, start, local_min, local_max;
const char *dev_n = dev_name(&device_obj->device);
u32 fb_end = screen_info.lfb_base + (screen_info.lfb_size << 1);
@@ -1170,12 +1170,22 @@ int vmbus_allocate_mmio(struct resource **new, struct 
hv_device *device_obj,
 
start = (local_min + align - 1) & ~(align - 1);
for (; start + size - 1 <= local_max; start += align) {
+   shadow = __request_region(iter, start,
+ size,
+ NULL,
+ IORESOURCE_BUSY);
+   if (!shadow)
+   continue;
+
*new = request_mem_region_exclusive(start, size,
dev_n);
if (*new) {
+   shadow->name = (char *)*new;
retval = 0;
goto exit;
}
+
+   __release_region(iter, start, size);
}
}
}
@@ -1196,7 +1206,17 @@ EXPORT_SYMBOL_GPL(vmbus_allocate_mmio);
  */
 void vmbus_free_mmio(resource_size_t start, resource_size_t size)
 {
+   struct resource *iter;
+
+   down(&hyperv_mmio_lock);
+   for (iter = hyperv_mmio; iter; iter = iter->sibling) {
+   if ((iter->start >= start + size) || (iter->end <= start))
+   continue;
+
+   __release_region(iter, start, size);
+   }
release_mem_region(start, size);
+   up(&hyperv_mmio_lock);
 
 }
 EXPORT_SYMBOL_GPL(vmbus_free_mmio);
-- 
1.7.4.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 7/7] drivers:hv: Separate out frame buffer logic when picking MMIO range

2016-04-05 Thread K. Y. Srinivasan
From: Jake Oshins 

Simplify the logic that picks MMIO ranges by pulling out the
logic related to trying to lay frame buffer claim on top of where
the firmware placed the frame buffer.

Signed-off-by: Jake Oshins 
Signed-off-by: K. Y. Srinivasan 
---
Greg, please apply this to the 4.6 tree.

 drivers/hv/vmbus_drv.c |   80 +---
 1 files changed, 35 insertions(+), 45 deletions(-)

diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index eaa5c3b..a29a6c0 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -1162,64 +1162,54 @@ int vmbus_allocate_mmio(struct resource **new, struct 
hv_device *device_obj,
bool fb_overlap_ok)
 {
struct resource *iter, *shadow;
-   resource_size_t range_min, range_max, start, local_min, local_max;
+   resource_size_t range_min, range_max, start;
const char *dev_n = dev_name(&device_obj->device);
-   u32 fb_end = screen_info.lfb_base + (screen_info.lfb_size << 1);
-   int i, retval;
+   int retval;
 
retval = -ENXIO;
down(&hyperv_mmio_lock);
 
+   /*
+* If overlaps with frame buffers are allowed, then first attempt to
+* make the allocation from within the reserved region.  Because it
+* is already reserved, no shadow allocation is necessary.
+*/
+   if (fb_overlap_ok && fb_mmio && !(min > fb_mmio->end) &&
+   !(max < fb_mmio->start)) {
+
+   range_min = fb_mmio->start;
+   range_max = fb_mmio->end;
+   start = (range_min + align - 1) & ~(align - 1);
+   for (; start + size - 1 <= range_max; start += align) {
+   *new = request_mem_region_exclusive(start, size, dev_n);
+   if (*new) {
+   retval = 0;
+   goto exit;
+   }
+   }
+   }
+
for (iter = hyperv_mmio; iter; iter = iter->sibling) {
if ((iter->start >= max) || (iter->end <= min))
continue;
 
range_min = iter->start;
range_max = iter->end;
-
-   /* If this range overlaps the frame buffer, split it into
-  two tries. */
-   for (i = 0; i < 2; i++) {
-   local_min = range_min;
-   local_max = range_max;
-   if (fb_overlap_ok || (range_min >= fb_end) ||
-   (range_max <= screen_info.lfb_base)) {
-   i++;
-   } else {
-   if ((range_min <= screen_info.lfb_base) &&
-   (range_max >= screen_info.lfb_base)) {
-   /*
-* The frame buffer is in this window,
-* so trim this into the part that
-* preceeds the frame buffer.
-*/
-   local_max = screen_info.lfb_base - 1;
-   range_min = fb_end;
-   } else {
-   range_min = fb_end;
-   continue;
-   }
+   start = (range_min + align - 1) & ~(align - 1);
+   for (; start + size - 1 <= range_max; start += align) {
+   shadow = __request_region(iter, start, size, NULL,
+ IORESOURCE_BUSY);
+   if (!shadow)
+   continue;
+
+   *new = request_mem_region_exclusive(start, size, dev_n);
+   if (*new) {
+   shadow->name = (char *)*new;
+   retval = 0;
+   goto exit;
}
 
-   start = (local_min + align - 1) & ~(align - 1);
-   for (; start + size - 1 <= local_max; start += align) {
-   shadow = __request_region(iter, start,
- size,
- NULL,
- IORESOURCE_BUSY);
-   if (!shadow)
-   continue;
-
-   *new = request_mem_region_exclusive(start, size,
-   dev_n);
-   if (*new) {
-   shadow->name = (char *)*new;
-   retval = 0;
-   goto exit;
- 

[PATCH 6/7] drivers:hv: Record MMIO range in use by frame buffer

2016-04-05 Thread K. Y. Srinivasan
From: Jake Oshins 

Later in the boot sequence, we need to figure out which memory
ranges can be given out to various paravirtual drivers.  The
hyperv_fb driver should, ideally, be placed right on top of
the frame buffer, without some other device getting plopped on
top of this range in the meantime.  Recording this now allows
that to be guaranteed.

Signed-off-by: Jake Oshins 
Signed-off-by: K. Y. Srinivasan 
---
Greg, please apply this to the 4.6 tree.

 drivers/hv/vmbus_drv.c |   37 -
 1 files changed, 36 insertions(+), 1 deletions(-)

diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index dfc6149..eaa5c3b 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -41,6 +41,7 @@
 #include 
 #include 
 #include 
+#include 
 #include "hyperv_vmbus.h"
 
 static struct acpi_device  *hv_acpi_dev;
@@ -101,6 +102,8 @@ static struct notifier_block hyperv_panic_block = {
.notifier_call = hyperv_panic_event,
 };
 
+static const char *fb_mmio_name = "fb_range";
+static struct resource *fb_mmio;
 struct resource *hyperv_mmio;
 DEFINE_SEMAPHORE(hyperv_mmio_lock);
 
@@ -1091,6 +1094,12 @@ static int vmbus_acpi_remove(struct acpi_device *device)
struct resource *next_res;
 
if (hyperv_mmio) {
+   if (fb_mmio) {
+   __release_region(hyperv_mmio, fb_mmio->start,
+resource_size(fb_mmio));
+   fb_mmio = NULL;
+   }
+
for (cur_res = hyperv_mmio; cur_res; cur_res = next_res) {
next_res = cur_res->sibling;
kfree(cur_res);
@@ -1100,6 +1109,30 @@ static int vmbus_acpi_remove(struct acpi_device *device)
return 0;
 }
 
+static void vmbus_reserve_fb(void)
+{
+   int size;
+   /*
+* Make a claim for the frame buffer in the resource tree under the
+* first node, which will be the one below 4GB.  The length seems to
+* be underreported, particularly in a Generation 1 VM.  So start out
+* reserving a larger area and make it smaller until it succeeds.
+*/
+
+   if (screen_info.lfb_base) {
+   if (efi_enabled(EFI_BOOT))
+   size = max_t(__u32, screen_info.lfb_size, 0x80);
+   else
+   size = max_t(__u32, screen_info.lfb_size, 0x400);
+
+   for (; !fb_mmio && (size >= 0x10); size >>= 1) {
+   fb_mmio = __request_region(hyperv_mmio,
+  screen_info.lfb_base, size,
+  fb_mmio_name, 0);
+   }
+   }
+}
+
 /**
  * vmbus_allocate_mmio() - Pick a memory-mapped I/O range.
  * @new:   If successful, supplied a pointer to the
@@ -1261,8 +1294,10 @@ static int vmbus_acpi_add(struct acpi_device *device)
 
if (ACPI_FAILURE(result))
continue;
-   if (hyperv_mmio)
+   if (hyperv_mmio) {
+   vmbus_reserve_fb();
break;
+   }
}
ret_val = 0;
 
-- 
1.7.4.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 2/7] drivers:hv: Make a function to free mmio regions through vmbus

2016-04-05 Thread K. Y. Srinivasan
From: Jake Oshins 

This patch introduces a function that reverses everything
done by vmbus_allocate_mmio().  Existing code just called
release_mem_region().  Future patches in this series
require a more complex sequence of actions, so this function
is introduced to wrap those actions.

Signed-off-by: Jake Oshins 
Signed-off-by: K. Y. Srinivasan 
---
Greg, please apply this to the 4.6 tree.

 drivers/hv/vmbus_drv.c |   15 +++
 include/linux/hyperv.h |2 +-
 2 files changed, 16 insertions(+), 1 deletions(-)

diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index 799518b..60553c1 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -1188,6 +1188,21 @@ exit:
 EXPORT_SYMBOL_GPL(vmbus_allocate_mmio);
 
 /**
+ * vmbus_free_mmio() - Free a memory-mapped I/O range.
+ * @start: Base address of region to release.
+ * @size:  Size of the range to be allocated
+ *
+ * This function releases anything requested by
+ * vmbus_mmio_allocate().
+ */
+void vmbus_free_mmio(resource_size_t start, resource_size_t size)
+{
+   release_mem_region(start, size);
+
+}
+EXPORT_SYMBOL_GPL(vmbus_free_mmio);
+
+/**
  * vmbus_cpu_number_to_vp_number() - Map CPU to VP.
  * @cpu_number: CPU number in Linux terms
  *
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index aa0fadc..ecd81c3 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -1091,7 +1091,7 @@ int vmbus_allocate_mmio(struct resource **new, struct 
hv_device *device_obj,
resource_size_t min, resource_size_t max,
resource_size_t size, resource_size_t align,
bool fb_overlap_ok);
-
+void vmbus_free_mmio(resource_size_t start, resource_size_t size);
 int vmbus_cpu_number_to_vp_number(int cpu_number);
 u64 hv_do_hypercall(u64 control, void *input, void *output);
 
-- 
1.7.4.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 1/7] drivers:hv: Lock access to hyperv_mmio resource tree

2016-04-05 Thread K. Y. Srinivasan
From: Jake Oshins 

In existing code, this tree of resources is created
in single-threaded code and never modified after it is
created, and thus needs no locking.  This patch introduces
a semaphore for tree access, as other patches in this
series introduce run-time modifications of this resource
tree which can happen on multiple threads.

Signed-off-by: Jake Oshins 
Signed-off-by: K. Y. Srinivasan 
---
Greg, please apply this to the 4.6 tree.

 drivers/hv/vmbus_drv.c |   16 
 1 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index 64713ff..799518b 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -102,6 +102,7 @@ static struct notifier_block hyperv_panic_block = {
 };
 
 struct resource *hyperv_mmio;
+DEFINE_SEMAPHORE(hyperv_mmio_lock);
 
 static int vmbus_exists(void)
 {
@@ -1132,7 +1133,10 @@ int vmbus_allocate_mmio(struct resource **new, struct 
hv_device *device_obj,
resource_size_t range_min, range_max, start, local_min, local_max;
const char *dev_n = dev_name(&device_obj->device);
u32 fb_end = screen_info.lfb_base + (screen_info.lfb_size << 1);
-   int i;
+   int i, retval;
+
+   retval = -ENXIO;
+   down(&hyperv_mmio_lock);
 
for (iter = hyperv_mmio; iter; iter = iter->sibling) {
if ((iter->start >= max) || (iter->end <= min))
@@ -1169,13 +1173,17 @@ int vmbus_allocate_mmio(struct resource **new, struct 
hv_device *device_obj,
for (; start + size - 1 <= local_max; start += align) {
*new = request_mem_region_exclusive(start, size,
dev_n);
-   if (*new)
-   return 0;
+   if (*new) {
+   retval = 0;
+   goto exit;
+   }
}
}
}
 
-   return -ENXIO;
+exit:
+   up(&hyperv_mmio_lock);
+   return retval;
 }
 EXPORT_SYMBOL_GPL(vmbus_allocate_mmio);
 
-- 
1.7.4.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 0/7] drivers: hv: Ensure that bridge windows don't overlap

2016-04-05 Thread K. Y. Srinivasan
Greg, please apply this set to 4.6 tree.

Hyper-V VMs expose paravirtual drivers through a mechanism called
VMBus, which is managed by hv_vmbus.ko.  For each parvirtual service
instance, this driver exposes a new child device.  Some of these child
devices need memory address space, into which Hyper-V will map things
like the virtual video frame buffer.  This memory-mapped address space
is chosen by the guest OS, not the hypervisor.

This is difficult to map onto the Linux pnp layer, as the code in the
pnp layer to choose MMIO space keys off of bus type and it doesn't know
anything about VMBus.  The maintainers of the pnp layer have asked that
we not offer patches to it that make it understand VMBus, but that we
rather find ways of using the code in its current state.  So hv_vmbus.ko
exports a function, vmbus_allocate_mmio() for choosing the address space
for any child driver that needs this facility.

The recently introduced PCI front-end driver for Hyper-V VMs
(pci-hyperv.ko) uses vmbus_allocate_mmio() for choosing both the region
of memory space into which real PCI Express devices are mapped.  The
regions allocated are made to look like root PCI bus bridge windows
to the PCI driver, reusing all the code in the PCI driver for the rest
of PCI device management.

The problem is that these bridge windows are marked in such a way that
devices can still allocate from the memory space spanned by them, and
this means that if two different PCI buses are created in the VM, each
with devices under them, they may allocate the same memory space, leading
to PCI Base Address Register which overlap.

This patch series fixes the problem by tracking allocations to child
devices in a separate resource tree, marking them such that the bridge
windows can't overlap.  The main memory resource tree, iomem_resource,
contains resources properly marked as bridge windows, allowing their
children to overlap with them.


Jake Oshins (7):
  drivers:hv: Lock access to hyperv_mmio resource tree
  drivers:hv: Make a function to free mmio regions through vmbus
  drivers:hv: Use new vmbus_mmio_free() from client drivers.
  drivers:hv: Reverse order of resources in hyperv_mmio
  drivers:hv: Track allocations of children of hv_vmbus in private
resource tree
  drivers:hv: Record MMIO range in use by frame buffer
  drivers:hv: Separate out frame buffer logic when picking MMIO range

 drivers/hv/vmbus_drv.c  |  143 --
 drivers/pci/host/pci-hyperv.c   |   14 ++--
 drivers/video/fbdev/hyperv_fb.c |4 +-
 include/linux/hyperv.h  |2 +-
 4 files changed, 115 insertions(+), 48 deletions(-)

-- 
1.7.4.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH] staging: android: make function static

2016-04-05 Thread Sudip Mukherjee
The only user of ion_handle_put() is within the file ion.c, so we can
safely make it static. Just to be double sure, checked the function
ion_handle_get() which is static.
So we can make ion_handle_put() static.

Signed-off-by: Sudip Mukherjee 
---
 drivers/staging/android/ion/ion.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/staging/android/ion/ion.c 
b/drivers/staging/android/ion/ion.c
index d4c6207..bbc8bc5 100644
--- a/drivers/staging/android/ion/ion.c
+++ b/drivers/staging/android/ion/ion.c
@@ -396,7 +396,7 @@ static int ion_handle_put_nolock(struct ion_handle *handle)
return ret;
 }
 
-int ion_handle_put(struct ion_handle *handle)
+static int ion_handle_put(struct ion_handle *handle)
 {
struct ion_client *client = handle->client;
int ret;
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: Staging: unisys/verisonic: Correct double unlock

2016-04-05 Thread Neil Horman
On Mon, Apr 04, 2016 at 09:40:13PM +, Sell, Timothy C wrote:
> > -Original Message-
> > From: Neil Horman [mailto:nhor...@redhat.com]
> > Sent: Monday, April 04, 2016 10:35 AM
> > To: Sell, Timothy C
> > Cc: Iban Rodriguez; Kershner, David A; Greg Kroah-Hartman; Benjamin
> > Romer; *S-Par-Maintainer; de...@driverdev.osuosl.org; linux-
> > ker...@vger.kernel.org
> > Subject: Re: Staging: unisys/verisonic: Correct double unlock
> > 
> > On Sat, Apr 02, 2016 at 11:20:14PM +, Sell, Timothy C wrote:
> > > > -Original Message-
> > > > From: Iban Rodriguez [mailto:iban.rodrig...@ono.com]
> > > > Sent: Saturday, April 02, 2016 1:47 PM
> > > > To: Kershner, David A; Greg Kroah-Hartman; Benjamin Romer; Sell,
> > Timothy
> > > > C; Neil Horman
> > > > Cc: *S-Par-Maintainer; de...@driverdev.osuosl.org; linux-
> > > > ker...@vger.kernel.org; Iban Rodriguez
> > > > Subject: Staging: unisys/verisonic: Correct double unlock
> > > >
> > > > 'priv_lock' is unlocked twice. The first one is removed and
> > > > the function 'visornic_serverdown_complete' is now called with
> > > > 'priv_lock' locked because 'devdata' is modified inside.
> > > >
> > > > Signed-off-by: Iban Rodriguez 
> > > > ---
> > > >  drivers/staging/unisys/visornic/visornic_main.c | 1 -
> > > >  1 file changed, 1 deletion(-)
> > > >
> > > > diff --git a/drivers/staging/unisys/visornic/visornic_main.c
> > > > b/drivers/staging/unisys/visornic/visornic_main.c
> > > > index be0d057346c3..af03f2938fe9 100644
> > > > --- a/drivers/staging/unisys/visornic/visornic_main.c
> > > > +++ b/drivers/staging/unisys/visornic/visornic_main.c
> > > > @@ -368,7 +368,6 @@ visornic_serverdown(struct visornic_devdata
> > > > *devdata,
> > > > }
> > > > devdata->server_change_state = true;
> > > > devdata->server_down_complete_func = complete_func;
> > > > -   spin_unlock_irqrestore(&devdata->priv_lock, flags);
> > > > visornic_serverdown_complete(devdata);
> > > > } else if (devdata->server_change_state) {
> > > > dev_dbg(&devdata->dev->device, "%s changing state\n",
> > >
> > > I agree there is a bug here involving priv_lock being unlocked
> > > twice, but this patch isn't the appropriate fix.  Reason is, we can NOT
> > > call visornic_serverdown_complete() while holding a spinlock
> > > (which is what this patch would cause to occur) because
> > > visornic_serverdown_complete() might block when it calls
> > > rtnl_lock() in this code sequence (rtnl_lock() grabs a mutex):
> > >
> > > rtnl_lock();
> > > dev_close(netdev);
> > > rtnl_unlock();
> > >
> > > Blocking with a spinlock held is always a bad idea.  :-(
> > >
> > 
> > You should just get rid of the priv_lock entirely, its not needed.
> > 
> > priv_lock is used the following functions:
> > 
> > visornic_serverdown - only called at the end of a tx_timeout reset
> > operation, so
> > you are sure that the rx and tx paths are quiesced (i.e. no data access
> > happening)
> > 
> > visornic_disable_with_timeout - move the netif_stop_queue operation to
> > the top
> > of this function and you will be guaranteed no concurrent access in the tx
> > path
> > 
> > visornic_enable_with_timeout - same as above, make sure that
> > netif_start_queue
> > and napi_enable are at the end of the function and you are guarantted no
> > concurrent access.
> > 
> > visornic_xmit - The queue lock in the netdev_start_xmit routine guarantees
> > you
> > single access here from multiple transmits.
> > 
> > visornic_xmit_timeout - only called on a tx timeout, when you are
> > guaranteed not
> > to have concurrent transmit occuing, by definition.
> > 
> > visornic_rx - the only tests made here are to devdata members that are
> > altered
> > in service_resp_queue, and the visornic_rx is only called from
> > service_resp_queue, so you are guaranteed a stable data structure, as there
> > is
> > only ever one context in service_resp_queue as its called from the napi poll
> > routine
> > 
> > service_resp_queue - Same as above, for any given queue,
> > service_resp_queue only
> > has one context exectuing at once.
> > 
> > host_side_disappeared - only called from visornic_remove, when implies
> > that all
> > associated devices are closed already, guaranteeing single access.
> > 
> > visornic_remove
> > visornic_resume - Both of these function only get called when all network
> > interfaces are quiesced.
> > 
> > just remove the lock and make the minor changes needed to guarantee
> > isolated
> > access.  It makes the code cleaner and faster
> > 
> > Neil
> 
> Neil, 
> 
> Although I would also love to get rid of this lock, I think we still
> need it, and will attempt to explain.
> 
> There's a thread of execution present in visornic  that doesn't exist
> in traditional network drivers, which involves the visornic_pause() and
> visornic_resume() functions registered during:
> 
> visorbus_register_visor_driver(&visornic_d

[PATCH] staging/lustre/obdclass: fix build warning

2016-04-05 Thread Sudip Mukherjee
While building with W=1 we were getting the warning:

drivers/staging/lustre/lustre/obdclass/cl_object.c:1056:16:
warning: old-style function definition
 struct lu_env *cl_env_percpu_get()
^

Signed-off-by: Sudip Mukherjee 
---
 drivers/staging/lustre/lustre/obdclass/cl_object.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/staging/lustre/lustre/obdclass/cl_object.c 
b/drivers/staging/lustre/lustre/obdclass/cl_object.c
index 395b92c..d84ec00 100644
--- a/drivers/staging/lustre/lustre/obdclass/cl_object.c
+++ b/drivers/staging/lustre/lustre/obdclass/cl_object.c
@@ -1053,7 +1053,7 @@ void cl_env_percpu_put(struct lu_env *env)
 }
 EXPORT_SYMBOL(cl_env_percpu_put);
 
-struct lu_env *cl_env_percpu_get()
+struct lu_env *cl_env_percpu_get(void)
 {
struct cl_env *cle;
 
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH] staging: comedi: das1800: remove unused variable

2016-04-05 Thread Sudip Mukherjee
The variable unipolar was never used.

Signed-off-by: Sudip Mukherjee 
---

There may be a chance that reading from DAS1800_CONTROL_C is necessary
before reading from DAS1800_STATUS. If that is true then please discard
this patch.

 drivers/staging/comedi/drivers/das1800.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/staging/comedi/drivers/das1800.c 
b/drivers/staging/comedi/drivers/das1800.c
index 94078118..76cf2cd 100644
--- a/drivers/staging/comedi/drivers/das1800.c
+++ b/drivers/staging/comedi/drivers/das1800.c
@@ -482,9 +482,6 @@ static void das1800_handle_fifo_not_empty(struct 
comedi_device *dev,
 {
struct comedi_cmd *cmd = &s->async->cmd;
unsigned short dpnt;
-   int unipolar;
-
-   unipolar = inb(dev->iobase + DAS1800_CONTROL_C) & UB;
 
while (inb(dev->iobase + DAS1800_STATUS) & FNE) {
dpnt = inw(dev->iobase + DAS1800_FIFO);
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH] Staging: android: timed_gpio: fixed bare use of 'unsigned'

2016-04-05 Thread Greg KH
On Tue, Apr 05, 2016 at 07:02:54PM +0530, Shyam Saini wrote:
> hi,
> Sorry for duplicate work, actually i was following http://kernelnewbies.org/
> FirstKernelPatch .
> I updated the repository, then i watched this video  and finally submitted the
> duplicate patch.
> 
> As you said, I should work against linux -next.
> So, Now, i'm following https://www.kernel.org/doc/man-pages/linux-next.html.
> May you  please tell me whether i'm on right track or not?

Yes, that sounds correct, you can also read
Documentation/development_process/ to see all of the details as to how
linux-next ties into all of the other subsystem trees.

good luck!

greg k-h
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH 08/27] staging: lustre: avoid to use bio->bi_vcnt directly

2016-04-05 Thread Christoph Hellwig
The lloop driver should be removed entirely - use the loop driver
instead.
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH 08/27] staging: lustre: avoid to use bio->bi_vcnt directly

2016-04-05 Thread Greg Kroah-Hartman
On Tue, Apr 05, 2016 at 07:56:53PM +0800, Ming Lei wrote:
> Signed-off-by: Ming Lei 

A bit more of a commit message is always nice :)

Acked-by: Greg Kroah-Hartman 
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 08/27] staging: lustre: avoid to use bio->bi_vcnt directly

2016-04-05 Thread Ming Lei
Signed-off-by: Ming Lei 
---
 drivers/staging/lustre/lustre/llite/lloop.c | 9 +
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/staging/lustre/lustre/llite/lloop.c 
b/drivers/staging/lustre/lustre/llite/lloop.c
index b725fc1..67323db 100644
--- a/drivers/staging/lustre/lustre/llite/lloop.c
+++ b/drivers/staging/lustre/lustre/llite/lloop.c
@@ -302,19 +302,20 @@ static unsigned int loop_get_bio(struct lloop_device *lo, 
struct bio **req)
}
 
/* TODO: need to split the bio, too bad. */
-   LASSERT(first->bi_vcnt <= LLOOP_MAX_SEGMENTS);
+   LASSERT(bio_pages(first) <= LLOOP_MAX_SEGMENTS);
 
rw = first->bi_rw;
bio = &lo->lo_bio;
while (*bio && (*bio)->bi_rw == rw) {
+   unsigned curr_cnt = bio_pages(*bio);
CDEBUG(D_INFO, "bio sector %llu size %u count %u vcnt%u\n",
   (unsigned long long)(*bio)->bi_iter.bi_sector,
   (*bio)->bi_iter.bi_size,
-  page_count, (*bio)->bi_vcnt);
-   if (page_count + (*bio)->bi_vcnt > LLOOP_MAX_SEGMENTS)
+  page_count, curr_cnt);
+   if (page_count + curr_cnt > LLOOP_MAX_SEGMENTS)
break;
 
-   page_count += (*bio)->bi_vcnt;
+   page_count += curr_cnt;
count++;
bio = &(*bio)->bi_next;
}
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 00/27] block: cleanup direct access on .bi_vcnt & .bi_io_vec

2016-04-05 Thread Ming Lei
Hi Guys,

It is always not a good practice to access bio->bi_vcnt and
bio->bi_io_vec from drivers directly. Also this kind of direct
access will cause trouble when converting to multipage bvecs.

The 1st patch introduces the following 4 bio helpers which can be
used inside drivers for avoiding direct access to .bi_vcnt and .bi_io_vec.

bio_pages()
bio_is_full()
bio_get_base_vec()
bio_set_vec_table()

Both bio_pages() and bio_is_full() can be easy to convert to
multipage bvecs.

For bio_get_base_vec() and bio_set_vec_table(), they are often used
during initializing a new bio or in case of single bvec bio. With the
two new helpers, it becomes quite easy to audit access to .bi_io_vec
and .bi_vcnt.

Most of the other patches use the 4 helpers to clean up most of direct
access to .bi_vcnt and .bi_io_vec from drivers, except for MD and btrfs,
which two subsystems will be done in the future. 

Also bio_add_page() is used in floppy, dm-crypt and fs/logfs to
avoiding direct access to .bi_vcnt & .bi_io_vec.

Thanks,
Ming

Ming Lei (27):
  block: bio: introduce 4 helpers for cleanup
  block: drbd: use bio_get_base_vec() to retrieve the 1st bvec
  block: drbd: remove impossible failure handling
  block: loop: use bio_get_base_vec() to retrive bvec table
  block: pktcdvd: use bio_get_base_vec() to retrive bvec table
  block: floppy: use bio_set_vec_table()
  block: floppy: use bio_add_page()
  staging: lustre: avoid to use bio->bi_vcnt directly
  target: use bio_is_full()
  bcache: debug: avoid to access .bi_io_vec directly
  bcache: io.c: use bio_set_vec_table
  bcache: journal.c: use bio_set_vec_table()
  bcache: movinggc: use bio_set_vec_table()
  bcache: writeback: use bio_set_vec_table()
  bcache: super: use bio_set_vec_table()
  bcache: super: use bio_get_base_vec
  dm: crypt: use bio_add_page()
  dm: dm-io.c: use bio_get_base_vec()
  dm: dm.c: replace 'bio->bi_vcnt == 1' with !bio_multiple_segments
  dm: dm-bufio.c: use bio_set_vec_table()
  fs: logfs: use bio_set_vec_table()
  fs: logfs: convert to bio_add_page() in sync_request()
  fs: logfs: use bio_add_page() in __bdev_writeseg()
  fs: logfs: use bio_add_page() in do_erase()
  fs: logfs: remove unnecesary check
  kernel/power/swap.c: use bio_get_base_vec()
  mm: page_io.c: use bio_get_base_vec()

 drivers/block/drbd/drbd_bitmap.c|   4 +-
 drivers/block/drbd/drbd_receiver.c  |  14 +---
 drivers/block/floppy.c  |   9 +--
 drivers/block/loop.c|   5 +-
 drivers/block/pktcdvd.c |   3 +-
 drivers/md/bcache/debug.c   |  11 ++-
 drivers/md/bcache/io.c  |   3 +-
 drivers/md/bcache/journal.c |   3 +-
 drivers/md/bcache/movinggc.c|   6 +-
 drivers/md/bcache/super.c   |  28 +---
 drivers/md/bcache/writeback.c   |   4 +-
 drivers/md/dm-bufio.c   |   3 +-
 drivers/md/dm-crypt.c   |   8 +--
 drivers/md/dm-io.c  |   7 +-
 drivers/md/dm.c |   3 +-
 drivers/staging/lustre/lustre/llite/lloop.c |   9 +--
 drivers/target/target_core_pscsi.c  |   2 +-
 fs/logfs/dev_bdev.c | 107 +++-
 include/linux/bio.h |  28 
 kernel/power/swap.c |  10 ++-
 mm/page_io.c|  18 -
 21 files changed, 156 insertions(+), 129 deletions(-)

-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 2/2] staging: dgnc: remove redundant NULL check in

2016-04-05 Thread Daeseok Youn
There were already checking NULL about channel_t / un_t
before calling dgnc_maxcps_room().

Signed-off-by: Daeseok Youn 
---
 drivers/staging/dgnc/dgnc_tty.c | 15 ++-
 1 file changed, 2 insertions(+), 13 deletions(-)

diff --git a/drivers/staging/dgnc/dgnc_tty.c b/drivers/staging/dgnc/dgnc_tty.c
index e97faaa..200d3aa 100644
--- a/drivers/staging/dgnc/dgnc_tty.c
+++ b/drivers/staging/dgnc/dgnc_tty.c
@@ -1536,19 +1536,8 @@ static int dgnc_tty_chars_in_buffer(struct tty_struct 
*tty)
  */
 static int dgnc_maxcps_room(struct tty_struct *tty, int bytes_available)
 {
-   struct channel_t *ch = NULL;
-   struct un_t *un = NULL;
-
-   if (!tty)
-   return bytes_available;
-
-   un = tty->driver_data;
-   if (!un || un->magic != DGNC_UNIT_MAGIC)
-   return bytes_available;
-
-   ch = un->un_ch;
-   if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
-   return bytes_available;
+   struct un_t *un = tty->driver_data;
+   struct channel_t *ch = un->un_ch;
 
/*
 * If its not the Transparent print device, return
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 1/2] staging: dgnc: return -ENOMEM when kzalloc failed

2016-04-05 Thread Daeseok Youn
The kzalloc can be failed when memory is not enough
to allocate. When kzalloc failed, it need to return
error code with ENOMEM

Signed-off-by: Daeseok Youn 
---
 drivers/staging/dgnc/dgnc_tty.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/drivers/staging/dgnc/dgnc_tty.c b/drivers/staging/dgnc/dgnc_tty.c
index 074988d..e97faaa 100644
--- a/drivers/staging/dgnc/dgnc_tty.c
+++ b/drivers/staging/dgnc/dgnc_tty.c
@@ -1106,6 +1106,14 @@ static int dgnc_tty_open(struct tty_struct *tty, struct 
file *file)
if (!ch->ch_wqueue)
ch->ch_wqueue = kzalloc(WQUEUESIZE, GFP_KERNEL);
 
+   if (!ch->ch_rqueue || !ch->ch_equeue || !ch->ch_wqueue) {
+   kfree(ch->ch_rqueue);
+   kfree(ch->ch_equeue);
+   kfree(ch->ch_wqueue);
+
+   return -ENOMEM;
+   }
+
spin_lock_irqsave(&ch->ch_lock, flags);
 
ch->ch_flags &= ~(CH_OPENING);
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel