* Re: [RFC][PATCH] KVM: Introduce direct MSI message injection for in-kernel irqchips
From: Jan Kiszka @ 2011-10-24 12:06 UTC (permalink / raw)
To: Avi Kivity; +Cc: Marcelo Tosatti, kvm, Michael S. Tsirkin
In-Reply-To: <4EA54759.902@redhat.com>
On 2011-10-24 13:09, Avi Kivity wrote:
> On 10/24/2011 12:19 PM, Jan Kiszka wrote:
>>>
>>> With the new feature it may be worthwhile, but I'd like to see the whole
>>> thing, with numbers attached.
>>
>> It's not a performance issue, it's a resource limitation issue: With the
>> new API we can stop worrying about user space device models consuming
>> limited IRQ routes of the KVM subsystem.
>>
>
> Only if those devices are in the same process (or have access to the
> vmfd). Interrupt routing together with irqfd allows you to disaggregate
> the device model. Instead of providing a competing implementation with
> new limitations, we need to remove the limitations of the old
> implementation.
That depends on where we do the cut. Currently we let the IRQ source
signal an abstract edge on a pre-allocated pseudo IRQ line. But we
cannot build correct MSI-X on top of the current irqfd model as we lack
the level information (for PBA emulation). *) So we either need to
extend the existing model anyway -- or push per-vector masking back to
the IRQ source. In the latter case, it would be a very good chance to
give up on limited pseudo GSIs with static routes and do MSI messaging
from external IRQ sources to KVM directly.
But all those considerations affect different APIs than what I'm
proposing here. We will always need a way to inject MSIs in the context
of the VM as there will always be scenarios where devices are better run
in that very same context, for performance or simplicity or whatever
reasons. E.g., I could imagine that one would like to execute an
emulated IRQ remapper rather in the hypervisor context than
"over-microkernelized" in a separate process.
Jan
*) Realized this while trying to generalize the proposed MSI-X MMIO
acceleration for assigned devices to arbitrary device models, vhost-net,
and specifically vfio.
--
Siemens AG, Corporate Technology, CT T DE IT 1
Corporate Competence Center Embedded Linux
^ permalink raw reply
* Re: [PATCH 1/3] ASoC: wm8940: Fix setting PLL Output clock division ratio
From: Girdwood, Liam @ 2011-10-24 12:06 UTC (permalink / raw)
To: Axel Lin; +Cc: linux-kernel, Mark Brown, Dimitris Papastamos, alsa-devel
In-Reply-To: <1319427161.5773.3.camel@phoenix>
On 24 October 2011 04:32, Axel Lin <axel.lin@gmail.com> wrote:
> According to the datasheet:
> The PLL Output clock division ratio is controlled by BIT[5:4] of
> WM8940_GPIO register(08h).
> Current code read/write the WM8940_ADDCNTRL(07h) register which is wrong.
>
> Signed-off-by: Axel Lin <axel.lin@gmail.com>
> ---
> sound/soc/codecs/wm8940.c | 4 ++--
> 1 files changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/sound/soc/codecs/wm8940.c b/sound/soc/codecs/wm8940.c
> index a4abfdf..3cc3bce 100644
> --- a/sound/soc/codecs/wm8940.c
> +++ b/sound/soc/codecs/wm8940.c
> @@ -627,8 +627,8 @@ static int wm8940_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
> ret = snd_soc_write(codec, WM8940_CLOCK, reg | (div << 5));
> break;
> case WM8940_OPCLKDIV:
> - reg = snd_soc_read(codec, WM8940_ADDCNTRL) & 0xFFCF;
> - ret = snd_soc_write(codec, WM8940_ADDCNTRL, reg | (div << 4));
> + reg = snd_soc_read(codec, WM8940_GPIO) & 0xFFCF;
> + ret = snd_soc_write(codec, WM8940_GPIO, reg | (div << 4));
> break;
> }
> return ret;
> --
Acked-by: Liam Girdwood <lrg@ti.com>
^ permalink raw reply
* Re: [B.A.T.M.A.N.] [PATCH] batman-adv: remove references for global tt entries
From: Marek Lindner @ 2011-10-24 12:05 UTC (permalink / raw)
To: The list for a Better Approach To Mobile Ad-hoc Networking
In-Reply-To: <4EA3E1A9.6020801@fisher-privat.net>
On Sunday, October 23, 2011 11:43:05 Alexey Fisher wrote:
> On 23.10.2011 11:40, Antonio Quartulli wrote:
> > Hello,
> >
> > On Wed, Oct 19, 2011 at 11:02:25AM +0200, Simon Wunderlich wrote:
> >> struct tt_global_entry holds a reference to an orig_node which must be
> >> decremented before deallocating the structure.
> >>
> >> Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
> >> ---
> >
> > I got a feedback on IRC from fishor_ who applied the patch while trying
> > to eliminate the kernel panic problem on module unload. The refcount has
> > not been printed, therefore we do not know if the patch really corrects
> > it but at least we know that this patch doesn't crash batman-adv :-)
> >
> > Cheers,
>
> tested-by: Alexey Fisher <bug-track@fisher-privat.net>
Patch was applied in revision 5da9ad7.
Thanks,
Marek
^ permalink raw reply
* kernel panic
From: nick bray @ 2011-10-24 11:19 UTC (permalink / raw)
To: linux-kernel
Hi,
after upgrading to linux kernel 3.xx I get kernel panic on boot unless
I use ACPI=off in the boot parameters this happens with both Ubuntu
11.10 and Fedora 16. The mainboard is an Intel S875WP1-E running a
Pentuim 4 3ghz with 3gig RAM in single-channel mode. I have performed a
Bios upgrade just in case tha ACPI tables were corrupt but it makes no
difference. Currently running 2.6.38-11-generic #50-Ubuntu SMP (Linux
Mint) with no issues. I can provide a screenshot if you wish but it's
looking like it's ACPI related as above.
Yours sincerely
Nick Bray
^ permalink raw reply
* Re: [Qemu-devel] qemu-kvm guest which won't 'cont' (emulation failure?)
From: Chris Webb @ 2011-10-24 12:05 UTC (permalink / raw)
To: Kevin Wolf; +Cc: qemu-devel, kvm
In-Reply-To: <4EA54DD6.2090603@redhat.com>
Kevin Wolf <kwolf@redhat.com> writes:
> Good point... The only other thing that I can think of would be
> attaching gdb and setting a breakpoint in vm_stop() or something.
Perfect, that seems to identified what's going on very nicely:
(gdb) break vm_stop
Breakpoint 1 at 0x407d10: file /home/root/packages/qemu-kvm/src-UMBurO/cpus.c, line 318.
(gdb) fg
Continuing.
Breakpoint 1, vm_stop (reason=0)
at /home/root/packages/qemu-kvm/src-UMBurO/cpus.c:318
318 /home/root/packages/qemu-kvm/src-UMBurO/cpus.c: No such file or directory.
in /home/root/packages/qemu-kvm/src-UMBurO/cpus.c
(gdb) bt
#0 vm_stop (reason=0) at /home/root/packages/qemu-kvm/src-UMBurO/cpus.c:318
#1 0x000000000058585f in ide_handle_rw_error (s=0x20330d8, error=28, op=8)
at /home/root/packages/qemu-kvm/src-UMBurO/hw/ide/core.c:468
#2 0x0000000000588376 in ide_dma_cb (opaque=0x20330d8,
ret=<value optimized out>)
at /home/root/packages/qemu-kvm/src-UMBurO/hw/ide/core.c:494
#3 0x0000000000590092 in dma_bdrv_cb (opaque=0x2043a10, ret=-28)
at /home/root/packages/qemu-kvm/src-UMBurO/dma-helpers.c:94
#4 0x000000000044d64a in qcow2_aio_write_cb (opaque=0x2034900, ret=-28)
at block/qcow2.c:714
#5 0x000000000043df6d in posix_aio_process_queue (
opaque=<value optimized out>) at posix-aio-compat.c:462
#6 0x000000000043e07d in posix_aio_read (opaque=0x17c8110)
at posix-aio-compat.c:503
#7 0x0000000000415fca in main_loop_wait (nonblocking=<value optimized out>)
at /home/root/packages/qemu-kvm/src-UMBurO/vl.c:1383
#8 0x000000000042ca37 in kvm_main_loop ()
at /home/root/packages/qemu-kvm/src-UMBurO/qemu-kvm.c:1589
#9 0x00000000004170a3 in main (argc=32, argv=<value optimized out>,
envp=<value optimized out>)
at /home/root/packages/qemu-kvm/src-UMBurO/vl.c:1429
I see what's happened here: we're not explicitly setting format=raw when we
start that guest and someone's uploaded a qcow2 image directly to a block
device. Ouch. Sorry for the noise!
Best wishes,
Chris.
^ permalink raw reply
* [Qemu-devel] [PATCH 3/5] qxl: support concurrent async commands
From: Alon Levy @ 2011-10-24 12:02 UTC (permalink / raw)
To: lcapitulino, armbru, kraxel; +Cc: mlureau, qemu-devel
In-Reply-To: <1319457739-14562-1-git-send-email-alevy@redhat.com>
change the single pending current_async to a linked list of pending
SpiceAsyncCommand.
Signed-off-by: Alon Levy <alevy@redhat.com>
---
hw/qxl-render.c | 2 +-
hw/qxl.c | 145 +++++++++++++++++++++++++++++++++++-----------------
hw/qxl.h | 29 +++++++++--
ui/spice-display.c | 19 ++++---
ui/spice-display.h | 7 ++-
5 files changed, 137 insertions(+), 65 deletions(-)
diff --git a/hw/qxl-render.c b/hw/qxl-render.c
index c290739..23a4289 100644
--- a/hw/qxl-render.c
+++ b/hw/qxl-render.c
@@ -125,7 +125,7 @@ void qxl_render_update(PCIQXLDevice *qxl)
memset(dirty, 0, sizeof(dirty));
qxl_spice_update_area(qxl, 0, &update,
- dirty, ARRAY_SIZE(dirty), 1, QXL_SYNC);
+ dirty, ARRAY_SIZE(dirty), 1, QXL_SYNC, 0);
for (i = 0; i < ARRAY_SIZE(dirty); i++) {
if (qemu_spice_rect_is_empty(dirty+i)) {
diff --git a/hw/qxl.c b/hw/qxl.c
index af02cda..008f5f7 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -120,7 +120,8 @@ static QXLMode qxl_modes[] = {
static PCIQXLDevice *qxl0;
static void qxl_send_events(PCIQXLDevice *d, uint32_t events);
-static int qxl_destroy_primary(PCIQXLDevice *d, qxl_async_io async);
+static int qxl_destroy_primary(PCIQXLDevice *d, qxl_async_io async,
+ uint64_t cookie);
static void qxl_reset_memslots(PCIQXLDevice *d);
static void qxl_reset_surfaces(PCIQXLDevice *d);
static void qxl_ring_set_dirty(PCIQXLDevice *qxl);
@@ -140,12 +141,11 @@ void qxl_guest_bug(PCIQXLDevice *qxl, const char *msg, ...)
}
}
-
void qxl_spice_update_area(PCIQXLDevice *qxl, uint32_t surface_id,
struct QXLRect *area, struct QXLRect *dirty_rects,
uint32_t num_dirty_rects,
uint32_t clear_dirty_region,
- qxl_async_io async)
+ qxl_async_io async, uint64_t cookie)
{
if (async == QXL_SYNC) {
qxl->ssd.worker->update_area(qxl->ssd.worker, surface_id, area,
@@ -153,7 +153,7 @@ void qxl_spice_update_area(PCIQXLDevice *qxl, uint32_t surface_id,
} else {
#if SPICE_INTERFACE_QXL_MINOR >= 1
spice_qxl_update_area_async(&qxl->ssd.qxl, surface_id, area,
- clear_dirty_region, 0);
+ clear_dirty_region, cookie);
#else
abort();
#endif
@@ -170,14 +170,13 @@ static void qxl_spice_destroy_surface_wait_complete(PCIQXLDevice *qxl,
}
static void qxl_spice_destroy_surface_wait(PCIQXLDevice *qxl, uint32_t id,
- qxl_async_io async)
+ qxl_async_io async, uint64_t cookie)
{
if (async) {
#if SPICE_INTERFACE_QXL_MINOR < 1
abort();
#else
- spice_qxl_destroy_surface_async(&qxl->ssd.qxl, id,
- (uint64_t)id);
+ spice_qxl_destroy_surface_async(&qxl->ssd.qxl, id, cookie);
#endif
} else {
qxl->ssd.worker->destroy_surface_wait(qxl->ssd.worker, id);
@@ -186,9 +185,9 @@ static void qxl_spice_destroy_surface_wait(PCIQXLDevice *qxl, uint32_t id,
}
#if SPICE_INTERFACE_QXL_MINOR >= 1
-static void qxl_spice_flush_surfaces_async(PCIQXLDevice *qxl)
+static void qxl_spice_flush_surfaces_async(PCIQXLDevice *qxl, uint64_t cookie)
{
- spice_qxl_flush_surfaces_async(&qxl->ssd.qxl, 0);
+ spice_qxl_flush_surfaces_async(&qxl->ssd.qxl, cookie);
}
#endif
@@ -216,13 +215,14 @@ static void qxl_spice_destroy_surfaces_complete(PCIQXLDevice *qxl)
qemu_mutex_unlock(&qxl->track_lock);
}
-static void qxl_spice_destroy_surfaces(PCIQXLDevice *qxl, qxl_async_io async)
+static void qxl_spice_destroy_surfaces(PCIQXLDevice *qxl, qxl_async_io async,
+ uint64_t cookie)
{
if (async) {
#if SPICE_INTERFACE_QXL_MINOR < 1
abort();
#else
- spice_qxl_destroy_surfaces_async(&qxl->ssd.qxl, 0);
+ spice_qxl_destroy_surfaces_async(&qxl->ssd.qxl, cookie);
#endif
} else {
qxl->ssd.worker->destroy_surfaces(qxl->ssd.worker);
@@ -736,17 +736,61 @@ static void qxl_create_guest_primary_complete(PCIQXLDevice *d);
#if SPICE_INTERFACE_QXL_MINOR >= 1
+SpiceAsyncCommand *push_spice_async_command(PCIQXLDevice *qxl,
+ uint32_t async_io, int size)
+{
+ assert(size >= sizeof(SpiceAsyncCommand));
+ SpiceAsyncCommand *spice_async_command = g_malloc0(size);
+
+ spice_async_command->cookie = qxl->async_next_cookie++;
+ spice_async_command->async_io = async_io;
+ QLIST_INSERT_HEAD(&qxl->async_commands, spice_async_command, next);
+ dprint(qxl, 2, "allocated async cookie %"PRId64"\n",
+ qxl->async_next_cookie - 1);
+ return spice_async_command;
+}
+
+/* caller must call g_free */
+static SpiceAsyncCommand *pop_spice_async_command(PCIQXLDevice *qxl,
+ uint64_t cookie)
+{
+ SpiceAsyncCommand *spice_async_command = NULL;
+
+ qemu_mutex_lock(&qxl->async_lock);
+ QLIST_FOREACH(spice_async_command, &qxl->async_commands, next) {
+ if (spice_async_command->cookie == cookie) {
+ QLIST_REMOVE(spice_async_command, next);
+ break;
+ }
+ }
+ qemu_mutex_unlock(&qxl->async_lock);
+ return spice_async_command;
+}
+
+/* can be called from any thread */
+void complete_spice_async_command(PCIQXLDevice *qxl,
+ SpiceAsyncCommand *spice_async_command)
+{
+ if (!spice_async_command->completion) {
+ return;
+ }
+ spice_async_command->completion(qxl, spice_async_command);
+}
+
/* called from spice server thread context only */
static void interface_async_complete(QXLInstance *sin, uint64_t cookie)
{
PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
uint32_t current_async;
+ SpiceAsyncCommand *spice_async_command;
- qemu_mutex_lock(&qxl->async_lock);
- current_async = qxl->current_async;
- qxl->current_async = QXL_UNDEFINED_IO;
- qemu_mutex_unlock(&qxl->async_lock);
-
+ spice_async_command = pop_spice_async_command(qxl, cookie);
+ if (!spice_async_command) {
+ dprint(qxl, 1, "async_complete: ERROR: response to not "
+ "pending operation, cookie=%ld\n", cookie);
+ return;
+ }
+ current_async = spice_async_command->async_io;
dprint(qxl, 2, "async_complete: %d (%ld) done\n", current_async, cookie);
switch (current_async) {
case QXL_IO_CREATE_PRIMARY_ASYNC:
@@ -756,9 +800,12 @@ static void interface_async_complete(QXLInstance *sin, uint64_t cookie)
qxl_spice_destroy_surfaces_complete(qxl);
break;
case QXL_IO_DESTROY_SURFACE_ASYNC:
- qxl_spice_destroy_surface_wait_complete(qxl, (uint32_t)cookie);
+ qxl_spice_destroy_surface_wait_complete(qxl,
+ (uint64_t)spice_async_command->opaque);
break;
}
+ complete_spice_async_command(qxl, spice_async_command);
+ g_free(spice_async_command);
qxl_send_events(qxl, QXL_INTERRUPT_IO_CMD);
}
@@ -805,7 +852,7 @@ static void qxl_exit_vga_mode(PCIQXLDevice *d)
return;
}
dprint(d, 1, "%s\n", __FUNCTION__);
- qxl_destroy_primary(d, QXL_SYNC);
+ qxl_destroy_primary(d, QXL_SYNC, 0);
}
static void qxl_update_irq(PCIQXLDevice *d)
@@ -886,14 +933,14 @@ static void qxl_vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
if (qxl->mode != QXL_MODE_VGA) {
dprint(qxl, 1, "%s\n", __FUNCTION__);
- qxl_destroy_primary(qxl, QXL_SYNC);
+ qxl_destroy_primary(qxl, QXL_SYNC, 0);
qxl_soft_reset(qxl);
}
vga_ioport_write(opaque, addr, val);
}
static void qxl_add_memslot(PCIQXLDevice *d, uint32_t slot_id, uint64_t delta,
- qxl_async_io async)
+ qxl_async_io async, uint64_t cookie)
{
static const int regions[] = {
QXL_RAM_RANGE_INDEX,
@@ -963,7 +1010,7 @@ static void qxl_add_memslot(PCIQXLDevice *d, uint32_t slot_id, uint64_t delta,
__FUNCTION__, memslot.slot_id,
memslot.virt_start, memslot.virt_end);
- qemu_spice_add_memslot(&d->ssd, &memslot, async);
+ qemu_spice_add_memslot(&d->ssd, &memslot, async, cookie);
d->guest_slots[slot_id].ptr = (void*)memslot.virt_start;
d->guest_slots[slot_id].size = memslot.virt_end - memslot.virt_start;
d->guest_slots[slot_id].delta = delta;
@@ -988,7 +1035,7 @@ static void qxl_reset_surfaces(PCIQXLDevice *d)
{
dprint(d, 1, "%s:\n", __FUNCTION__);
d->mode = QXL_MODE_UNDEFINED;
- qxl_spice_destroy_surfaces(d, QXL_SYNC);
+ qxl_spice_destroy_surfaces(d, QXL_SYNC, 0);
}
/* called from spice server thread context only */
@@ -1020,7 +1067,7 @@ static void qxl_create_guest_primary_complete(PCIQXLDevice *qxl)
}
static void qxl_create_guest_primary(PCIQXLDevice *qxl, int loadvm,
- qxl_async_io async)
+ qxl_async_io async, uint64_t cookie)
{
QXLDevSurfaceCreate surface;
QXLSurfaceCreate *sc = &qxl->guest_primary.surface;
@@ -1048,7 +1095,7 @@ static void qxl_create_guest_primary(PCIQXLDevice *qxl, int loadvm,
qxl->mode = QXL_MODE_NATIVE;
qxl->cmdflags = 0;
- qemu_spice_create_primary_surface(&qxl->ssd, 0, &surface, async);
+ qemu_spice_create_primary_surface(&qxl->ssd, 0, &surface, async, cookie);
if (async == QXL_SYNC) {
qxl_create_guest_primary_complete(qxl);
@@ -1057,7 +1104,8 @@ static void qxl_create_guest_primary(PCIQXLDevice *qxl, int loadvm,
/* return 1 if surface destoy was initiated (in QXL_ASYNC case) or
* done (in QXL_SYNC case), 0 otherwise. */
-static int qxl_destroy_primary(PCIQXLDevice *d, qxl_async_io async)
+static int qxl_destroy_primary(PCIQXLDevice *d, qxl_async_io async,
+ uint64_t cookie)
{
if (d->mode == QXL_MODE_UNDEFINED) {
return 0;
@@ -1066,7 +1114,7 @@ static int qxl_destroy_primary(PCIQXLDevice *d, qxl_async_io async)
dprint(d, 1, "%s\n", __FUNCTION__);
d->mode = QXL_MODE_UNDEFINED;
- qemu_spice_destroy_primary_surface(&d->ssd, 0, async);
+ qemu_spice_destroy_primary_surface(&d->ssd, 0, async, cookie);
return 1;
}
@@ -1097,10 +1145,10 @@ static void qxl_set_mode(PCIQXLDevice *d, int modenr, int loadvm)
}
d->guest_slots[0].slot = slot;
- qxl_add_memslot(d, 0, devmem, QXL_SYNC);
+ qxl_add_memslot(d, 0, devmem, QXL_SYNC, 0);
d->guest_primary.surface = surface;
- qxl_create_guest_primary(d, 0, QXL_SYNC);
+ qxl_create_guest_primary(d, 0, QXL_SYNC, 0);
d->mode = QXL_MODE_COMPAT;
d->cmdflags = QXL_COMMAND_FLAG_COMPAT;
@@ -1122,7 +1170,9 @@ static void ioport_write(void *opaque, target_phys_addr_t addr,
qxl_async_io async = QXL_SYNC;
#if SPICE_INTERFACE_QXL_MINOR >= 1
uint32_t orig_io_port = io_port;
+ SpiceAsyncCommand *spice_async_command = NULL;
#endif
+ uint64_t cookie = 0;
switch (io_port) {
case QXL_IO_RESET:
@@ -1179,15 +1229,12 @@ static void ioport_write(void *opaque, target_phys_addr_t addr,
async_common:
async = QXL_ASYNC;
qemu_mutex_lock(&d->async_lock);
- if (d->current_async != QXL_UNDEFINED_IO) {
- qxl_guest_bug(d, "%d async started before last (%d) complete",
- io_port, d->current_async);
- qemu_mutex_unlock(&d->async_lock);
- return;
- }
- d->current_async = orig_io_port;
+ spice_async_command = push_spice_async_command(d, orig_io_port,
+ sizeof(SpiceAsyncCommand));
qemu_mutex_unlock(&d->async_lock);
- dprint(d, 2, "start async %d (%"PRId64")\n", io_port, val);
+ cookie = spice_async_command->cookie;
+ dprint(d, 2, "start async %d (%"PRId64") cookie %"PRId64"\n", io_port,
+ val, cookie);
break;
default:
break;
@@ -1199,7 +1246,7 @@ async_common:
{
QXLRect update = d->ram->update_area;
qxl_spice_update_area(d, d->ram->update_surface,
- &update, NULL, 0, 0, async);
+ &update, NULL, 0, 0, async, cookie);
break;
}
case QXL_IO_NOTIFY_CMD:
@@ -1247,7 +1294,7 @@ async_common:
break;
}
d->guest_slots[val].slot = d->ram->mem_slot;
- qxl_add_memslot(d, val, 0, async);
+ qxl_add_memslot(d, val, 0, async, cookie);
break;
case QXL_IO_MEMSLOT_DEL:
if (val >= NUM_MEMSLOTS) {
@@ -1264,7 +1311,7 @@ async_common:
}
dprint(d, 1, "QXL_IO_CREATE_PRIMARY async=%d\n", async);
d->guest_primary.surface = d->ram->create_surface;
- qxl_create_guest_primary(d, 0, async);
+ qxl_create_guest_primary(d, 0, async, cookie);
break;
case QXL_IO_DESTROY_PRIMARY:
if (val != 0) {
@@ -1274,7 +1321,7 @@ async_common:
}
dprint(d, 1, "QXL_IO_DESTROY_PRIMARY (async=%d) (%s)\n", async,
qxl_mode_to_string(d->mode));
- if (!qxl_destroy_primary(d, async)) {
+ if (!qxl_destroy_primary(d, async, cookie)) {
dprint(d, 1, "QXL_IO_DESTROY_PRIMARY_ASYNC in %s, ignored\n",
qxl_mode_to_string(d->mode));
goto cancel_async;
@@ -1286,7 +1333,9 @@ async_common:
"%d >= NUM_SURFACES", async, val);
goto cancel_async;
}
- qxl_spice_destroy_surface_wait(d, val, async);
+ spice_async_command->opaque = (void *)(uint64_t)val;
+ qxl_spice_destroy_surface_wait(d, val, async,
+ spice_async_command->cookie);
break;
#if SPICE_INTERFACE_QXL_MINOR >= 1
case QXL_IO_FLUSH_RELEASE: {
@@ -1307,12 +1356,12 @@ async_common:
" (%"PRId64") (%s, s#=%d, res#=%d)\n",
val, qxl_mode_to_string(d->mode), d->guest_surfaces.count,
d->num_free_res);
- qxl_spice_flush_surfaces_async(d);
+ qxl_spice_flush_surfaces_async(d, cookie);
break;
#endif
case QXL_IO_DESTROY_ALL_SURFACES:
d->mode = QXL_MODE_UNDEFINED;
- qxl_spice_destroy_surfaces(d, async);
+ qxl_spice_destroy_surfaces(d, async, cookie);
break;
default:
fprintf(stderr, "%s: ioport=0x%x, abort()\n", __FUNCTION__, io_port);
@@ -1324,7 +1373,7 @@ cancel_async:
if (async) {
qxl_send_events(d, QXL_INTERRUPT_IO_CMD);
qemu_mutex_lock(&d->async_lock);
- d->current_async = QXL_UNDEFINED_IO;
+ pop_spice_async_command(d, spice_async_command->cookie);
qemu_mutex_unlock(&d->async_lock);
}
#else
@@ -1520,7 +1569,8 @@ static int qxl_init_common(PCIQXLDevice *qxl)
qxl->num_surfaces = NUM_SURFACES;
qemu_mutex_init(&qxl->track_lock);
qemu_mutex_init(&qxl->async_lock);
- qxl->current_async = QXL_UNDEFINED_IO;
+ QLIST_INIT(&qxl->async_commands);
+ qxl->async_next_cookie = 0;
switch (qxl->revision) {
case 1: /* spice 0.4 -- qxl-1 */
@@ -1697,9 +1747,9 @@ static int qxl_post_load(void *opaque, int version)
if (!d->guest_slots[i].active) {
continue;
}
- qxl_add_memslot(d, i, 0, QXL_SYNC);
+ qxl_add_memslot(d, i, 0, QXL_SYNC, 0);
}
- qxl_create_guest_primary(d, 1, QXL_SYNC);
+ qxl_create_guest_primary(d, 1, QXL_SYNC, 0);
/* replay surface-create and cursor-set commands */
cmds = g_malloc0(sizeof(QXLCommandExt) * (NUM_SURFACES + 1));
@@ -1718,7 +1768,6 @@ static int qxl_post_load(void *opaque, int version)
out++;
qxl_spice_loadvm_commands(d, cmds, out);
g_free(cmds);
-
break;
case QXL_MODE_COMPAT:
qxl_set_mode(d, d->shadow_rom.mode, 1);
diff --git a/hw/qxl.h b/hw/qxl.h
index 868db81..4c89e14 100644
--- a/hw/qxl.h
+++ b/hw/qxl.h
@@ -17,7 +17,22 @@ enum qxl_mode {
#define QXL_UNDEFINED_IO UINT32_MAX
-typedef struct PCIQXLDevice {
+typedef struct PCIQXLDevice PCIQXLDevice;
+typedef struct SpiceAsyncCommand SpiceAsyncCommand;
+typedef void (*SpiceAsyncCommandCompletion)(PCIQXLDevice *,
+ SpiceAsyncCommand *);
+
+/* Outstanding async request sent to spice server.
+ * cookie must be unique across the list. */
+struct SpiceAsyncCommand {
+ uint64_t cookie;
+ void *opaque;
+ uint32_t async_io;
+ SpiceAsyncCommandCompletion completion;
+ QLIST_ENTRY(SpiceAsyncCommand) next;
+};
+
+struct PCIQXLDevice {
PCIDevice pci;
SimpleSpiceDisplay ssd;
int id;
@@ -32,7 +47,8 @@ typedef struct PCIQXLDevice {
int32_t num_memslots;
int32_t num_surfaces;
- uint32_t current_async;
+ QLIST_HEAD(, SpiceAsyncCommand) async_commands;
+ uint64_t async_next_cookie;
QemuMutex async_lock;
struct guest_slots {
@@ -87,7 +103,7 @@ typedef struct PCIQXLDevice {
/* io bar */
MemoryRegion io_bar;
-} PCIQXLDevice;
+};
#define PANIC_ON(x) if ((x)) { \
printf("%s: PANIC %s failed\n", __FUNCTION__, #x); \
@@ -116,13 +132,18 @@ void qxl_spice_update_area(PCIQXLDevice *qxl, uint32_t surface_id,
struct QXLRect *area, struct QXLRect *dirty_rects,
uint32_t num_dirty_rects,
uint32_t clear_dirty_region,
- qxl_async_io async);
+ qxl_async_io async, uint64_t cookie);
void qxl_spice_loadvm_commands(PCIQXLDevice *qxl, struct QXLCommandExt *ext,
uint32_t count);
void qxl_spice_oom(PCIQXLDevice *qxl);
void qxl_spice_reset_memslots(PCIQXLDevice *qxl);
void qxl_spice_reset_image_cache(PCIQXLDevice *qxl);
void qxl_spice_reset_cursor(PCIQXLDevice *qxl);
+SpiceAsyncCommand *push_spice_async_command(PCIQXLDevice *qxl,
+ uint32_t async_io, int size);
+/* complete_spice_async_command: call to cleanup a command */
+void complete_spice_async_command(PCIQXLDevice *qxl,
+ SpiceAsyncCommand *spice_async_command);
/* qxl-logger.c */
void qxl_log_cmd_cursor(PCIQXLDevice *qxl, QXLCursorCmd *cmd, int group_id);
diff --git a/ui/spice-display.c b/ui/spice-display.c
index 6c302a3..71e7305 100644
--- a/ui/spice-display.c
+++ b/ui/spice-display.c
@@ -61,11 +61,11 @@ void qemu_spice_rect_union(QXLRect *dest, const QXLRect *r)
}
void qemu_spice_add_memslot(SimpleSpiceDisplay *ssd, QXLDevMemSlot *memslot,
- qxl_async_io async)
+ qxl_async_io async, uint64_t cookie)
{
if (async != QXL_SYNC) {
#if SPICE_INTERFACE_QXL_MINOR >= 1
- spice_qxl_add_memslot_async(&ssd->qxl, memslot, 0);
+ spice_qxl_add_memslot_async(&ssd->qxl, memslot, cookie);
#else
abort();
#endif
@@ -81,11 +81,11 @@ void qemu_spice_del_memslot(SimpleSpiceDisplay *ssd, uint32_t gid, uint32_t sid)
void qemu_spice_create_primary_surface(SimpleSpiceDisplay *ssd, uint32_t id,
QXLDevSurfaceCreate *surface,
- qxl_async_io async)
+ qxl_async_io async, uint64_t cookie)
{
if (async != QXL_SYNC) {
#if SPICE_INTERFACE_QXL_MINOR >= 1
- spice_qxl_create_primary_surface_async(&ssd->qxl, id, surface, 0);
+ spice_qxl_create_primary_surface_async(&ssd->qxl, id, surface, cookie);
#else
abort();
#endif
@@ -96,11 +96,12 @@ void qemu_spice_create_primary_surface(SimpleSpiceDisplay *ssd, uint32_t id,
void qemu_spice_destroy_primary_surface(SimpleSpiceDisplay *ssd,
- uint32_t id, qxl_async_io async)
+ uint32_t id, qxl_async_io async,
+ uint64_t cookie)
{
if (async != QXL_SYNC) {
#if SPICE_INTERFACE_QXL_MINOR >= 1
- spice_qxl_destroy_primary_surface_async(&ssd->qxl, id, 0);
+ spice_qxl_destroy_primary_surface_async(&ssd->qxl, id, cookie);
#else
abort();
#endif
@@ -223,7 +224,7 @@ void qemu_spice_create_host_memslot(SimpleSpiceDisplay *ssd)
memset(&memslot, 0, sizeof(memslot));
memslot.slot_group_id = MEMSLOT_GROUP_HOST;
memslot.virt_end = ~0;
- qemu_spice_add_memslot(ssd, &memslot, QXL_SYNC);
+ qemu_spice_add_memslot(ssd, &memslot, QXL_SYNC, 0);
}
void qemu_spice_create_host_primary(SimpleSpiceDisplay *ssd)
@@ -243,14 +244,14 @@ void qemu_spice_create_host_primary(SimpleSpiceDisplay *ssd)
surface.mem = (intptr_t)ssd->buf;
surface.group_id = MEMSLOT_GROUP_HOST;
- qemu_spice_create_primary_surface(ssd, 0, &surface, QXL_SYNC);
+ qemu_spice_create_primary_surface(ssd, 0, &surface, QXL_SYNC, 0);
}
void qemu_spice_destroy_host_primary(SimpleSpiceDisplay *ssd)
{
dprint(1, "%s:\n", __FUNCTION__);
- qemu_spice_destroy_primary_surface(ssd, 0, QXL_SYNC);
+ qemu_spice_destroy_primary_surface(ssd, 0, QXL_SYNC, 0);
}
void qemu_spice_vm_change_state_handler(void *opaque, int running,
diff --git a/ui/spice-display.h b/ui/spice-display.h
index 5e52df9..5db7eb8 100644
--- a/ui/spice-display.h
+++ b/ui/spice-display.h
@@ -99,14 +99,15 @@ void qemu_spice_display_resize(SimpleSpiceDisplay *ssd);
void qemu_spice_display_refresh(SimpleSpiceDisplay *ssd);
void qemu_spice_add_memslot(SimpleSpiceDisplay *ssd, QXLDevMemSlot *memslot,
- qxl_async_io async);
+ qxl_async_io async, uint64_t cookie);
void qemu_spice_del_memslot(SimpleSpiceDisplay *ssd, uint32_t gid,
uint32_t sid);
void qemu_spice_create_primary_surface(SimpleSpiceDisplay *ssd, uint32_t id,
QXLDevSurfaceCreate *surface,
- qxl_async_io async);
+ qxl_async_io async, uint64_t cookie);
void qemu_spice_destroy_primary_surface(SimpleSpiceDisplay *ssd,
- uint32_t id, qxl_async_io async);
+ uint32_t id, qxl_async_io async,
+ uint64_t cookie);
void qemu_spice_wakeup(SimpleSpiceDisplay *ssd);
void qemu_spice_start(SimpleSpiceDisplay *ssd);
void qemu_spice_stop(SimpleSpiceDisplay *ssd);
--
1.7.7
^ permalink raw reply related
* [Qemu-devel] [PATCH 5/5] qxl: support async monitor screen dump
From: Alon Levy @ 2011-10-24 12:02 UTC (permalink / raw)
To: lcapitulino, armbru, kraxel; +Cc: mlureau, qemu-devel
In-Reply-To: <1319457739-14562-1-git-send-email-alevy@redhat.com>
Split qxl_spice_update_area_complete from qxl_render_update, use
SPICE_INTERFACE_QXL_MINOR 2 introduced spice_qxl_update_area_dirty_async
to retrive the dirty rectangles asyncronously (the previous
spice_qxl_update_area_async did not accept a dirty rectangles array).
Introduce SpiceAsyncMonitorScreenDump for a screen_dump.
vga mode screen dumps are still synchronous.
Signed-off-by: Alon Levy <alevy@redhat.com>
---
patchcheck gives one false positive, identifying a point function
argument as a multiplication:
ERROR: need consistent spacing around '*' (ctx:WxV)
#135: FILE: hw/qxl.c:148:
+ SpiceAsyncCommand *async_command)
^
---
hw/qxl-render.c | 67 +++++++++++++++++++++++++++++---------
hw/qxl.c | 95 +++++++++++++++++++++++++++++++++++++++++++-----------
hw/qxl.h | 38 ++++++++++++++++++++--
3 files changed, 161 insertions(+), 39 deletions(-)
diff --git a/hw/qxl-render.c b/hw/qxl-render.c
index fd3c016..7dfd67f 100644
--- a/hw/qxl-render.c
+++ b/hw/qxl-render.c
@@ -27,6 +27,10 @@ static void qxl_flip(PCIQXLDevice *qxl, QXLRect *rect)
uint8_t *dst = qxl->guest_primary.flipped;
int len, i;
+ assert(rect->bottom >= 0);
+ assert(rect->bottom <= qxl->guest_primary.surface.height);
+ assert(rect->top >= 0);
+ assert(rect->top <= qxl->guest_primary.surface.height);
src += (qxl->guest_primary.surface.height - rect->top - 1) *
qxl->guest_primary.stride;
dst += rect->top * qxl->guest_primary.stride;
@@ -110,17 +114,39 @@ static void qxl_render_display_resized(PCIQXLDevice *qxl)
dpy_resize(vga->ds);
}
-void qxl_render_update(PCIQXLDevice *qxl)
+void qxl_spice_update_area_complete(PCIQXLDevice *qxl, QXLRect *dirty,
+ int n_dirty)
{
VGACommonState *vga = &qxl->vga;
- QXLRect dirty[32], update;
int i;
+ for (i = 0; i < n_dirty; i++) {
+ if (qemu_spice_rect_is_empty(dirty + i)) {
+ break;
+ }
+ if (qxl->guest_primary.flipped) {
+ qxl_flip(qxl, dirty + i);
+ }
+ dpy_update(vga->ds,
+ dirty[i].left, dirty[i].top,
+ dirty[i].right - dirty[i].left,
+ dirty[i].bottom - dirty[i].top);
+ }
+}
+
+void qxl_render_update(PCIQXLDevice *qxl,
+ SpiceAsyncMonitorScreenDump *async_screen_dump)
+{
+ QXLRect dirty[32], update;
+
if (qxl->guest_primary.resized) {
qxl_render_display_resized(qxl);
}
-
if (!qxl->guest_primary.commands) {
+ if (async_screen_dump) {
+ dprint(qxl, 2, "%s: no update required\n", __func__);
+ complete_spice_async_command(qxl, &async_screen_dump->base);
+ }
return;
}
qxl->guest_primary.commands = 0;
@@ -131,20 +157,29 @@ void qxl_render_update(PCIQXLDevice *qxl)
update.bottom = qxl->guest_primary.surface.height;
memset(dirty, 0, sizeof(dirty));
+ if (async_screen_dump) {
+#if SPICE_INTERFACE_QXL_MINOR >= 2
+ dprint(qxl, 2, "A-SYNC update_area 0 (%d,%d,%d,%d)\n",
+ update.top, update.left, update.bottom, update.right);
+ async_screen_dump->n_dirty = 32;
+ async_screen_dump->dirty = g_malloc0(sizeof(QXLRect) *
+ async_screen_dump->n_dirty);
+ qxl_spice_update_area(qxl, 0, &update,
+ async_screen_dump->dirty,
+ async_screen_dump->n_dirty, 1,
+ &async_screen_dump->base);
+ return;
+#else
+ fprintf(stderr, "%s: warning: fallback to sync, spice-server < 0.8.4\n",
+ __func__);
+#endif
+ }
+ dprint(qxl, 2, "SYNC update_area\n");
qxl_spice_update_area(qxl, 0, &update,
- dirty, ARRAY_SIZE(dirty), 1, QXL_SYNC, 0);
-
- for (i = 0; i < ARRAY_SIZE(dirty); i++) {
- if (qemu_spice_rect_is_empty(dirty+i)) {
- break;
- }
- if (qxl->guest_primary.flipped) {
- qxl_flip(qxl, dirty+i);
- }
- dpy_update(vga->ds,
- dirty[i].left, dirty[i].top,
- dirty[i].right - dirty[i].left,
- dirty[i].bottom - dirty[i].top);
+ dirty, ARRAY_SIZE(dirty), 1, NULL);
+ qxl_spice_update_area_complete(qxl, dirty, ARRAY_SIZE(dirty));
+ if (async_screen_dump) {
+ complete_spice_async_command(qxl, &async_screen_dump->base);
}
}
diff --git a/hw/qxl.c b/hw/qxl.c
index 008f5f7..a3e89cd 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -145,18 +145,32 @@ void qxl_spice_update_area(PCIQXLDevice *qxl, uint32_t surface_id,
struct QXLRect *area, struct QXLRect *dirty_rects,
uint32_t num_dirty_rects,
uint32_t clear_dirty_region,
- qxl_async_io async, uint64_t cookie)
+ SpiceAsyncCommand *async_command)
{
- if (async == QXL_SYNC) {
+ if (async_command == NULL) {
qxl->ssd.worker->update_area(qxl->ssd.worker, surface_id, area,
dirty_rects, num_dirty_rects, clear_dirty_region);
} else {
+#if SPICE_INTERFACE_QXL_MINOR >= 2
+ if (num_dirty_rects > 0) {
+ spice_qxl_update_area_dirty_async(&qxl->ssd.qxl, surface_id, area,
+ dirty_rects, num_dirty_rects,
+ clear_dirty_region,
+ async_command->cookie);
+ } else {
+ spice_qxl_update_area_async(&qxl->ssd.qxl, surface_id, area,
+ clear_dirty_region,
+ async_command->cookie);
+ }
+#else
#if SPICE_INTERFACE_QXL_MINOR >= 1
spice_qxl_update_area_async(&qxl->ssd.qxl, surface_id, area,
- clear_dirty_region, cookie);
+ clear_dirty_region,
+ async_command->cookie);
#else
abort();
-#endif
+#endif /* >= 1 */
+#endif /* >= 2 */
}
}
@@ -742,9 +756,11 @@ SpiceAsyncCommand *push_spice_async_command(PCIQXLDevice *qxl,
assert(size >= sizeof(SpiceAsyncCommand));
SpiceAsyncCommand *spice_async_command = g_malloc0(size);
+ qemu_mutex_lock(&qxl->async_lock);
spice_async_command->cookie = qxl->async_next_cookie++;
- spice_async_command->async_io = async_io;
+ spice_async_command->io = async_io;
QLIST_INSERT_HEAD(&qxl->async_commands, spice_async_command, next);
+ qemu_mutex_unlock(&qxl->async_lock);
dprint(qxl, 2, "allocated async cookie %"PRId64"\n",
qxl->async_next_cookie - 1);
return spice_async_command;
@@ -781,7 +797,7 @@ void complete_spice_async_command(PCIQXLDevice *qxl,
static void interface_async_complete(QXLInstance *sin, uint64_t cookie)
{
PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
- uint32_t current_async;
+ uint32_t io;
SpiceAsyncCommand *spice_async_command;
spice_async_command = pop_spice_async_command(qxl, cookie);
@@ -790,9 +806,9 @@ static void interface_async_complete(QXLInstance *sin, uint64_t cookie)
"pending operation, cookie=%ld\n", cookie);
return;
}
- current_async = spice_async_command->async_io;
- dprint(qxl, 2, "async_complete: %d (%ld) done\n", current_async, cookie);
- switch (current_async) {
+ io = spice_async_command->io;
+ dprint(qxl, 2, "async_complete: %d (%ld) done\n", io, cookie);
+ switch (io) {
case QXL_IO_CREATE_PRIMARY_ASYNC:
qxl_create_guest_primary_complete(qxl);
break;
@@ -806,7 +822,11 @@ static void interface_async_complete(QXLInstance *sin, uint64_t cookie)
}
complete_spice_async_command(qxl, spice_async_command);
g_free(spice_async_command);
- qxl_send_events(qxl, QXL_INTERRUPT_IO_CMD);
+ if (io <= QXL_IO_RANGE_SIZE) {
+ dprint(qxl, 2, "%s: calling qxl_send_events (cookie %"PRIu64")\n",
+ __func__, cookie);
+ qxl_send_events(qxl, QXL_INTERRUPT_IO_CMD);
+ }
}
#endif
@@ -1162,17 +1182,27 @@ static void qxl_set_mode(PCIQXLDevice *d, int modenr, int loadvm)
qxl_rom_set_dirty(d);
}
+typedef SpiceAsyncCommand *(*SpiceAsyncCommandCreator)(PCIQXLDevice *qxl,
+ uint32_t io, uint32_t val);
+
+static SpiceAsyncCommand *create_async_command(PCIQXLDevice *qxl, uint32_t io,
+ uint32_t val)
+{
+ return push_spice_async_command(qxl, io, sizeof(SpiceAsyncCommand));
+}
+
static void ioport_write(void *opaque, target_phys_addr_t addr,
uint64_t val, unsigned size)
{
PCIQXLDevice *d = opaque;
uint32_t io_port = addr;
qxl_async_io async = QXL_SYNC;
+ SpiceAsyncCommand *spice_async_command = NULL;
#if SPICE_INTERFACE_QXL_MINOR >= 1
uint32_t orig_io_port = io_port;
- SpiceAsyncCommand *spice_async_command = NULL;
#endif
uint64_t cookie = 0;
+ SpiceAsyncCommandCreator creator = create_async_command;
switch (io_port) {
case QXL_IO_RESET:
@@ -1228,10 +1258,7 @@ static void ioport_write(void *opaque, target_phys_addr_t addr,
case QXL_IO_FLUSH_SURFACES_ASYNC:
async_common:
async = QXL_ASYNC;
- qemu_mutex_lock(&d->async_lock);
- spice_async_command = push_spice_async_command(d, orig_io_port,
- sizeof(SpiceAsyncCommand));
- qemu_mutex_unlock(&d->async_lock);
+ spice_async_command = creator(d, orig_io_port, val);
cookie = spice_async_command->cookie;
dprint(d, 2, "start async %d (%"PRId64") cookie %"PRId64"\n", io_port,
val, cookie);
@@ -1246,7 +1273,7 @@ async_common:
{
QXLRect update = d->ram->update_area;
qxl_spice_update_area(d, d->ram->update_surface,
- &update, NULL, 0, 0, async, cookie);
+ &update, NULL, 0, 0, spice_async_command);
break;
}
case QXL_IO_NOTIFY_CMD:
@@ -1457,7 +1484,7 @@ static void qxl_hw_update(void *opaque)
break;
case QXL_MODE_COMPAT:
case QXL_MODE_NATIVE:
- qxl_render_update(qxl);
+ qxl_render_update(qxl, NULL);
break;
default:
break;
@@ -1472,6 +1499,36 @@ static void qxl_hw_invalidate(void *opaque)
vga->invalidate(vga);
}
+static void screen_dump_complete(PCIQXLDevice *qxl,
+ SpiceAsyncCommand *spice_async_command)
+{
+ SpiceAsyncMonitorScreenDump *async_screen_dump =
+ (SpiceAsyncMonitorScreenDump *)spice_async_command;
+
+ dprint(qxl, 2, "%s: calling screen_dump_cb >%s<\n", __func__,
+ async_screen_dump->filename);
+ qxl_spice_update_area_complete(qxl, async_screen_dump->dirty,
+ async_screen_dump->n_dirty);
+ g_free(async_screen_dump->dirty);
+ ppm_save(async_screen_dump->filename, qxl->ssd.ds->surface);
+ g_free((void *)async_screen_dump->filename);
+ async_screen_dump->cb(async_screen_dump->cb_opaque, NULL);
+}
+
+static SpiceAsyncMonitorScreenDump *push_screen_dump(PCIQXLDevice *qxl,
+ const char *filename, MonitorCompletion *cb, void *cb_opaque)
+{
+ SpiceAsyncMonitorScreenDump *async_command =
+ (SpiceAsyncMonitorScreenDump *)
+ push_spice_async_command(qxl, MONITOR_UPDATE_AREA_ASYNC,
+ sizeof(SpiceAsyncMonitorScreenDump));
+ async_command->cb = cb;
+ async_command->cb_opaque = cb_opaque;
+ async_command->filename = g_strdup(filename);
+ async_command->base.completion = screen_dump_complete;
+ return async_command;
+}
+
static void qxl_hw_screen_dump(void *opaque, const char *filename,
MonitorCompletion *cb, void *cb_opaque)
{
@@ -1481,9 +1538,7 @@ static void qxl_hw_screen_dump(void *opaque, const char *filename,
switch (qxl->mode) {
case QXL_MODE_COMPAT:
case QXL_MODE_NATIVE:
- qxl_render_update(qxl);
- ppm_save(filename, qxl->ssd.ds->surface);
- cb(cb_opaque, NULL);
+ qxl_render_update(qxl, push_screen_dump(qxl, filename, cb, cb_opaque));
break;
case QXL_MODE_VGA:
vga->screen_dump(vga, filename, cb, cb_opaque);
diff --git a/hw/qxl.h b/hw/qxl.h
index 4c89e14..2375c03 100644
--- a/hw/qxl.h
+++ b/hw/qxl.h
@@ -17,6 +17,26 @@ enum qxl_mode {
#define QXL_UNDEFINED_IO UINT32_MAX
+/* The monitor's screen_dump triggers a update_area
+ * command which must be done asynchroniously to prevent the following
+ * deadlock scenario when the spice client is also a monitor client and
+ * is running single threaded:
+ *
+ * io thread worker thread client
+ *
+ * <---------------------------------------------------- screendump
+ * do_screen_dump-> read------->
+ * flush, read
+ * client socket------------->
+ *
+ * To avoid adding these to the spice-protocol/spice/qxl_dev.h, they
+ * are defined here. */
+enum {
+ /* Must start larger then QXL_IO_RANGE_SIZE, but that is a moving
+ * target, so split in half. */
+ MONITOR_UPDATE_AREA_ASYNC = 0x80000000,
+};
+
typedef struct PCIQXLDevice PCIQXLDevice;
typedef struct SpiceAsyncCommand SpiceAsyncCommand;
typedef void (*SpiceAsyncCommandCompletion)(PCIQXLDevice *,
@@ -27,11 +47,20 @@ typedef void (*SpiceAsyncCommandCompletion)(PCIQXLDevice *,
struct SpiceAsyncCommand {
uint64_t cookie;
void *opaque;
- uint32_t async_io;
+ uint32_t io;
SpiceAsyncCommandCompletion completion;
QLIST_ENTRY(SpiceAsyncCommand) next;
};
+typedef struct SpiceAsyncMonitorScreenDump {
+ SpiceAsyncCommand base;
+ MonitorCompletion *cb;
+ void *cb_opaque;
+ const char *filename;
+ QXLRect *dirty;
+ int n_dirty;
+} SpiceAsyncMonitorScreenDump;
+
struct PCIQXLDevice {
PCIDevice pci;
SimpleSpiceDisplay ssd;
@@ -132,7 +161,7 @@ void qxl_spice_update_area(PCIQXLDevice *qxl, uint32_t surface_id,
struct QXLRect *area, struct QXLRect *dirty_rects,
uint32_t num_dirty_rects,
uint32_t clear_dirty_region,
- qxl_async_io async, uint64_t cookie);
+ SpiceAsyncCommand *async_command);
void qxl_spice_loadvm_commands(PCIQXLDevice *qxl, struct QXLCommandExt *ext,
uint32_t count);
void qxl_spice_oom(PCIQXLDevice *qxl);
@@ -151,11 +180,14 @@ void qxl_log_command(PCIQXLDevice *qxl, const char *ring, QXLCommandExt *ext);
/* qxl-render.c */
void qxl_render_resize(PCIQXLDevice *qxl);
-void qxl_render_update(PCIQXLDevice *qxl);
+void qxl_render_update(PCIQXLDevice *qxl,
+ SpiceAsyncMonitorScreenDump *async_screen_dump);
void qxl_render_cursor(PCIQXLDevice *qxl, QXLCommandExt *ext);
#if SPICE_INTERFACE_QXL_MINOR >= 1
void qxl_spice_update_area_async(PCIQXLDevice *qxl, uint32_t surface_id,
struct QXLRect *area,
uint32_t clear_dirty_region,
int is_vga);
+void qxl_spice_update_area_complete(PCIQXLDevice *qxl, QXLRect *dirty,
+ int n_dirty);
#endif
--
1.7.7
^ permalink raw reply related
* [Qemu-devel] [PATCH 2/5] qxl: s/__FUNCTION__/__func__/, change logging levels
From: Alon Levy @ 2011-10-24 12:02 UTC (permalink / raw)
To: lcapitulino, armbru, kraxel; +Cc: mlureau, qemu-devel
In-Reply-To: <1319457739-14562-1-git-send-email-alevy@redhat.com>
---
hw/qxl.c | 8 ++++----
1 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/hw/qxl.c b/hw/qxl.c
index 4003e53..af02cda 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -515,7 +515,7 @@ static int interface_get_command(QXLInstance *sin, struct QXLCommandExt *ext)
switch (qxl->mode) {
case QXL_MODE_VGA:
- dprint(qxl, 2, "%s: vga\n", __FUNCTION__);
+ dprint(qxl, 4, "%s: vga\n", __func__);
ret = false;
qemu_mutex_lock(&qxl->ssd.lock);
if (qxl->ssd.update != NULL) {
@@ -526,19 +526,19 @@ static int interface_get_command(QXLInstance *sin, struct QXLCommandExt *ext)
}
qemu_mutex_unlock(&qxl->ssd.lock);
if (ret) {
- dprint(qxl, 2, "%s %s\n", __FUNCTION__, qxl_mode_to_string(qxl->mode));
+ dprint(qxl, 4, "%s %s\n", __func__, qxl_mode_to_string(qxl->mode));
qxl_log_command(qxl, "vga", ext);
}
return ret;
case QXL_MODE_COMPAT:
case QXL_MODE_NATIVE:
case QXL_MODE_UNDEFINED:
- dprint(qxl, 4, "%s: %s\n", __FUNCTION__, qxl_mode_to_string(qxl->mode));
+ dprint(qxl, 5, "%s: %s\n", __func__, qxl_mode_to_string(qxl->mode));
ring = &qxl->ram->cmd_ring;
if (SPICE_RING_IS_EMPTY(ring)) {
return false;
}
- dprint(qxl, 2, "%s: %s\n", __FUNCTION__, qxl_mode_to_string(qxl->mode));
+ dprint(qxl, 4, "%s: %s\n", __func__, qxl_mode_to_string(qxl->mode));
SPICE_RING_CONS_ITEM(ring, cmd);
ext->cmd = *cmd;
ext->group_id = MEMSLOT_GROUP_GUEST;
--
1.7.7
^ permalink raw reply related
* [Qemu-devel] [PATCH 1/5] monitor: screen_dump async
From: Alon Levy @ 2011-10-24 12:02 UTC (permalink / raw)
To: lcapitulino, armbru, kraxel; +Cc: mlureau, qemu-devel
In-Reply-To: <1319457739-14562-1-git-send-email-alevy@redhat.com>
Make screen_dump monitor command an async command to allow next for qxl
to implement it as a initiating call to red_worker and completion on
callback, to fix a deadlock when issueing a screendump command via
libvirt while connected with a libvirt controlled spice-gtk client.
This patch introduces no functional changes.
---
console.c | 5 +++--
console.h | 7 +++++--
hmp-commands.hx | 3 ++-
hw/g364fb.c | 12 ++++++++----
hw/qxl.c | 6 ++++--
hw/vga.c | 7 +++++--
hw/vmware_vga.c | 5 +++--
monitor.c | 5 +++--
qmp-commands.hx | 3 ++-
9 files changed, 35 insertions(+), 18 deletions(-)
diff --git a/console.c b/console.c
index e43de92..30c667a 100644
--- a/console.c
+++ b/console.c
@@ -173,7 +173,8 @@ void vga_hw_invalidate(void)
active_console->hw_invalidate(active_console->hw);
}
-void vga_hw_screen_dump(const char *filename)
+void vga_hw_screen_dump(const char *filename, MonitorCompletion cb,
+ void *opaque)
{
TextConsole *previous_active_console;
@@ -183,7 +184,7 @@ void vga_hw_screen_dump(const char *filename)
so always dump the first one. */
console_select(0);
if (consoles[0] && consoles[0]->hw_screen_dump) {
- consoles[0]->hw_screen_dump(consoles[0]->hw, filename);
+ consoles[0]->hw_screen_dump(consoles[0]->hw, filename, cb, opaque);
}
console_select(previous_active_console->index);
diff --git a/console.h b/console.h
index 9c1487e..dde4088 100644
--- a/console.h
+++ b/console.h
@@ -343,7 +343,9 @@ static inline void console_write_ch(console_ch_t *dest, uint32_t ch)
typedef void (*vga_hw_update_ptr)(void *);
typedef void (*vga_hw_invalidate_ptr)(void *);
-typedef void (*vga_hw_screen_dump_ptr)(void *, const char *);
+typedef void (*vga_hw_screen_dump_ptr)(void *, const char *,
+ MonitorCompletion *,
+ void *);
typedef void (*vga_hw_text_update_ptr)(void *, console_ch_t *);
DisplayState *graphic_console_init(vga_hw_update_ptr update,
@@ -354,7 +356,8 @@ DisplayState *graphic_console_init(vga_hw_update_ptr update,
void vga_hw_update(void);
void vga_hw_invalidate(void);
-void vga_hw_screen_dump(const char *filename);
+void vga_hw_screen_dump(const char *filename, MonitorCompletion cb,
+ void *opaque);
void vga_hw_text_update(console_ch_t *chardata);
int is_graphic_console(void);
diff --git a/hmp-commands.hx b/hmp-commands.hx
index ab08d58..a7b3494 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -157,7 +157,8 @@ ETEXI
.params = "filename",
.help = "save screen into PPM image 'filename'",
.user_print = monitor_user_noop,
- .mhandler.cmd_new = do_screen_dump,
+ .mhandler.cmd_async = do_screen_dump,
+ .flags = MONITOR_CMD_ASYNC,
},
STEXI
diff --git a/hw/g364fb.c b/hw/g364fb.c
index f00ee27..5884e20 100644
--- a/hw/g364fb.c
+++ b/hw/g364fb.c
@@ -291,7 +291,8 @@ static void g364fb_reset(G364State *s)
g364fb_invalidate_display(s);
}
-static void g364fb_screen_dump(void *opaque, const char *filename)
+static void g364fb_screen_dump(void *opaque, const char *filename,
+ MonitorCompletion *cb, void *cb_opaque)
{
G364State *s = opaque;
int y, x;
@@ -303,12 +304,13 @@ static void g364fb_screen_dump(void *opaque, const char *filename)
if (s->depth != 8) {
error_report("g364: unknown guest depth %d", s->depth);
- return;
+ goto end;
}
f = fopen(filename, "wb");
- if (!f)
- return;
+ if (!f) {
+ goto end;
+ }
if (s->ctla & CTLA_FORCE_BLANK) {
/* blank screen */
@@ -331,6 +333,8 @@ static void g364fb_screen_dump(void *opaque, const char *filename)
}
fclose(f);
+end:
+ cb(cb_opaque, NULL);
}
/* called for accesses to io ports */
diff --git a/hw/qxl.c b/hw/qxl.c
index 03848ed..4003e53 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -1423,7 +1423,8 @@ static void qxl_hw_invalidate(void *opaque)
vga->invalidate(vga);
}
-static void qxl_hw_screen_dump(void *opaque, const char *filename)
+static void qxl_hw_screen_dump(void *opaque, const char *filename,
+ MonitorCompletion *cb, void *cb_opaque)
{
PCIQXLDevice *qxl = opaque;
VGACommonState *vga = &qxl->vga;
@@ -1433,9 +1434,10 @@ static void qxl_hw_screen_dump(void *opaque, const char *filename)
case QXL_MODE_NATIVE:
qxl_render_update(qxl);
ppm_save(filename, qxl->ssd.ds->surface);
+ cb(cb_opaque, NULL);
break;
case QXL_MODE_VGA:
- vga->screen_dump(vga, filename);
+ vga->screen_dump(vga, filename, cb, cb_opaque);
break;
default:
break;
diff --git a/hw/vga.c b/hw/vga.c
index ca79aa1..b257f74 100644
--- a/hw/vga.c
+++ b/hw/vga.c
@@ -148,7 +148,8 @@ static uint32_t expand4[256];
static uint16_t expand2[256];
static uint8_t expand4to8[16];
-static void vga_screen_dump(void *opaque, const char *filename);
+static void vga_screen_dump(void *opaque, const char *filename,
+ MonitorCompletion *cb, void *cb_opaque);
static const char *screen_dump_filename;
static DisplayChangeListener *screen_dump_dcl;
@@ -2404,7 +2405,8 @@ static DisplayChangeListener* vga_screen_dump_init(DisplayState *ds)
/* save the vga display in a PPM image even if no display is
available */
-static void vga_screen_dump(void *opaque, const char *filename)
+static void vga_screen_dump(void *opaque, const char *filename,
+ MonitorCompletion *cb, void *cb_opaque)
{
VGACommonState *s = opaque;
@@ -2415,4 +2417,5 @@ static void vga_screen_dump(void *opaque, const char *filename)
vga_invalidate_display(s);
vga_hw_update();
screen_dump_filename = NULL;
+ cb(cb_opaque, NULL);
}
diff --git a/hw/vmware_vga.c b/hw/vmware_vga.c
index af70bde..a238fef 100644
--- a/hw/vmware_vga.c
+++ b/hw/vmware_vga.c
@@ -1003,11 +1003,12 @@ static void vmsvga_invalidate_display(void *opaque)
/* save the vga display in a PPM image even if no display is
available */
-static void vmsvga_screen_dump(void *opaque, const char *filename)
+static void vmsvga_screen_dump(void *opaque, const char *filename,
+ MonitorCompletion *cb, void *cb_opaque)
{
struct vmsvga_state_s *s = opaque;
if (!s->enable) {
- s->vga.screen_dump(&s->vga, filename);
+ s->vga.screen_dump(&s->vga, filename, cb, cb_opaque);
return;
}
diff --git a/monitor.c b/monitor.c
index ffda0fe..daf5e2f 100644
--- a/monitor.c
+++ b/monitor.c
@@ -1180,9 +1180,10 @@ static int client_migrate_info(Monitor *mon, const QDict *qdict, QObject **ret_d
return -1;
}
-static int do_screen_dump(Monitor *mon, const QDict *qdict, QObject **ret_data)
+static int do_screen_dump(Monitor *mon, const QDict *params,
+ MonitorCompletion cb, void *opaque)
{
- vga_hw_screen_dump(qdict_get_str(qdict, "filename"));
+ vga_hw_screen_dump(qdict_get_str(params, "filename"), cb, opaque);
return 0;
}
diff --git a/qmp-commands.hx b/qmp-commands.hx
index 9c11e87..15b04d6 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -155,7 +155,8 @@ EQMP
.params = "filename",
.help = "save screen into PPM image 'filename'",
.user_print = monitor_user_noop,
- .mhandler.cmd_new = do_screen_dump,
+ .mhandler.cmd_async = do_screen_dump,
+ .flags = MONITOR_CMD_ASYNC,
},
SQMP
--
1.7.7
^ permalink raw reply related
* [Qemu-devel] [PATCH 4/5] qxl: split qxl_render_display_resized
From: Alon Levy @ 2011-10-24 12:02 UTC (permalink / raw)
To: lcapitulino, armbru, kraxel; +Cc: mlureau, qemu-devel
In-Reply-To: <1319457739-14562-1-git-send-email-alevy@redhat.com>
Signed-off-by: Alon Levy <alevy@redhat.com>
---
hw/qxl-render.c | 75 ++++++++++++++++++++++++++++++-------------------------
1 files changed, 41 insertions(+), 34 deletions(-)
diff --git a/hw/qxl-render.c b/hw/qxl-render.c
index 23a4289..fd3c016 100644
--- a/hw/qxl-render.c
+++ b/hw/qxl-render.c
@@ -70,47 +70,54 @@ void qxl_render_resize(PCIQXLDevice *qxl)
}
}
+static void qxl_render_display_resized(PCIQXLDevice *qxl)
+{
+ VGACommonState *vga = &qxl->vga;
+ void *ptr;
+
+ qxl->guest_primary.resized = 0;
+
+ if (qxl->guest_primary.flipped) {
+ g_free(qxl->guest_primary.flipped);
+ qxl->guest_primary.flipped = NULL;
+ }
+ qemu_free_displaysurface(vga->ds);
+
+ qxl->guest_primary.data = memory_region_get_ram_ptr(&qxl->vga.vram);
+ if (qxl->guest_primary.stride < 0) {
+ /* spice surface is upside down -> need extra buffer to flip */
+ qxl->guest_primary.stride = -qxl->guest_primary.stride;
+ qxl->guest_primary.flipped = g_malloc(qxl->guest_primary.surface.width *
+ qxl->guest_primary.stride);
+ ptr = qxl->guest_primary.flipped;
+ } else {
+ ptr = qxl->guest_primary.data;
+ }
+ dprint(qxl, 1, "%s: %dx%d, stride %d, bpp %d, depth %d, flip %s\n",
+ __func__,
+ qxl->guest_primary.surface.width,
+ qxl->guest_primary.surface.height,
+ qxl->guest_primary.stride,
+ qxl->guest_primary.bytes_pp,
+ qxl->guest_primary.bits_pp,
+ qxl->guest_primary.flipped ? "yes" : "no");
+ vga->ds->surface =
+ qemu_create_displaysurface_from(qxl->guest_primary.surface.width,
+ qxl->guest_primary.surface.height,
+ qxl->guest_primary.bits_pp,
+ qxl->guest_primary.stride,
+ ptr);
+ dpy_resize(vga->ds);
+}
+
void qxl_render_update(PCIQXLDevice *qxl)
{
VGACommonState *vga = &qxl->vga;
QXLRect dirty[32], update;
- void *ptr;
int i;
if (qxl->guest_primary.resized) {
- qxl->guest_primary.resized = 0;
-
- if (qxl->guest_primary.flipped) {
- g_free(qxl->guest_primary.flipped);
- qxl->guest_primary.flipped = NULL;
- }
- qemu_free_displaysurface(vga->ds);
-
- qxl->guest_primary.data = memory_region_get_ram_ptr(&qxl->vga.vram);
- if (qxl->guest_primary.stride < 0) {
- /* spice surface is upside down -> need extra buffer to flip */
- qxl->guest_primary.stride = -qxl->guest_primary.stride;
- qxl->guest_primary.flipped = g_malloc(qxl->guest_primary.surface.width *
- qxl->guest_primary.stride);
- ptr = qxl->guest_primary.flipped;
- } else {
- ptr = qxl->guest_primary.data;
- }
- dprint(qxl, 1, "%s: %dx%d, stride %d, bpp %d, depth %d, flip %s\n",
- __FUNCTION__,
- qxl->guest_primary.surface.width,
- qxl->guest_primary.surface.height,
- qxl->guest_primary.stride,
- qxl->guest_primary.bytes_pp,
- qxl->guest_primary.bits_pp,
- qxl->guest_primary.flipped ? "yes" : "no");
- vga->ds->surface =
- qemu_create_displaysurface_from(qxl->guest_primary.surface.width,
- qxl->guest_primary.surface.height,
- qxl->guest_primary.bits_pp,
- qxl->guest_primary.stride,
- ptr);
- dpy_resize(vga->ds);
+ qxl_render_display_resized(qxl);
}
if (!qxl->guest_primary.commands) {
--
1.7.7
^ permalink raw reply related
* Re: [dm-crypt] [RFC] dm-crypt and hardware-optimized crypto modules
From: Jonas Meurer @ 2011-10-24 12:05 UTC (permalink / raw)
To: dm-crypt
In-Reply-To: <4EA505E5.5080205@redhat.com>
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Hey Milan,
Am 24.10.2011 08:29, schrieb Milan Broz:
> On 10/24/2011 01:30 AM, Jonas Meurer wrote:
>
>> In the Debian bugreport #639832 [1], Simon Mackinlay pointed out,
>> that hardware-optimized crypto driver modules aren't loaded
>> automatically at cryptsetup invokation in the boot process
>> (initramfs) in Debian.
>>
>> I verified this. At least for setups with aes support compiled
>> into the kernel, and hardware-optimized aes drivers (aes-x86_64,
>> aesni-intel) built as modules (which is the default for Debian
>> and Ubuntu kernels), the hardware-optimized aes modules aren't
>> loaded at cryptsetup invokation. (Sure, this is tested with
>> aes-encrypted volumes.) I didn't have time to check other setups
>> (e.g. everything built as modules) yet.
>
> If the modules are present at this time (either compiled-in or as
> separate modules) this seems to be kernel cryptoAPI bug.
It seems like this is the case, yes. I verified that
hardware-optimized modules are present in the initramfs both in Debian
and Ubuntu. I tested the 3.0.0-12-generic kernel in Ubuntu so far,
will check other kernels and setups later.
> If it is not present (in intramfs) then available module is used
> and later it is not replaced by hw accelerated driver.
Yes, that makes a lot of sense to me. But as written above, the
hardware-optimized drivers are available as modules at the time of
cryptsetup invokation.
> Anyway, I am using aesni_intel loaded from Debian initramfs and it
> works with no hacks. Wonder what is the difference... (kernel 3.0.3
> but compiled with own config to own kernel deb package.)
Do you have crypto drivers compiled into the kernel? Or built as
modules? I guess that software drivers built into the kernel and
hardware drivers available as modules is the only setup with problems,
but didn't test it yet.
>> I'm happy to extend the initramfs scripts to load
>> hardware-optimized modules in case they're available before
>> cryptsetup is invoked. But that an implementation would be ugly
>> and hard to maintain as it needs to be updated for possible
>> kernel crypto driver changes. I would prefer a solution where the
>> kernel crypto api took responsibility for this task.
>
> I think it should load modules automatically according to its
> priorities (hw has always higher priority). Anyway, this is the
> question for linux-crypto (kernel) list.
>
> There is no way how to force dm-crypt load specific driver.
Yes, I see the point that this is a issue for linux-crypto, and will
move the discussion to this list as soon as I did further investigation.
Thanks for your answers!
Greetings,
jonas
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/
iQIcBAEBAgAGBQJOpVRwAAoJEFJi5/9JEEn+LAMQAKLyIr8YZZMF2vYC/2pwN9WG
PI295FhABcdXCMuaD2GFbbW4euF7DSaknQF0uOFpxevm1wpXtlxOPFDPb6cD6YS2
9/n12quqVnfcgCsUo7cyWmZqZQylfQyuA6Xs/iamoaF7Y8SKXzLcazlNSRYHhCt9
lT03CdkTSGAR0g4Kbek8CT/lEjcjZ/DMO4OBCaPPZi9GppauW5eTu3yRvLZexZe7
xtiD2ZZoVu7YHIimMs/zbOvzi3Yo+nEPj6uQOeFkFjxHX/eMScKOcPzKX+KqvYqO
mDSMiMeDyxv5AVc8jdvgJUftbAIZ9mOPGxvIrI61v006KMHftC0NOlnlIz7xC7RG
E0XW+956sHLfDBRnfTe4dxuZYPHy4RjgwVJVBHvacSHl6IKu/jZHowadDglaF8NT
EJGdKRgnlkgAK3rb0APmBzd4WM/PY2Cew43Z5Ux1vLyH7/ZtXv6NlK6l7k6SBkoB
q4QChUlVzpLTKgZ5QCesMtyI/TVqjSHv3WEVOOwW3FLTT6riexYe6BzaHvoJUQXq
1DqmzCHhNjr6Fq5f++PuiKQSvb0MPn4dk+ZK7gXHshoNG05uSmXgTKr3l13oP9/5
XdiecNJF0eQjfSttLkc+T/LYVRlTanbyWODwlgPZaugDyDgBmUJsSyGV5xTt2w23
mZ4Rl1Au3UofuudPqf10
=Cu6i
-----END PGP SIGNATURE-----
^ permalink raw reply
* Re: [v2 PATCH 0/4] Implement byte-range lock caching
From: Pavel Shilovsky @ 2011-10-24 12:05 UTC (permalink / raw)
To: Jeff Layton, Steve French; +Cc: linux-cifs-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20111024073529.28e787a5-9yPaYZwiELC+kQycOl6kW4xkIHaj4LzF@public.gmane.org>
2011/10/24 Jeff Layton <jlayton-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>:
> On Sat, 22 Oct 2011 15:33:28 +0400
> Pavel Shilovsky <piastry-7qunaywFIewox3rIn2DAYQ@public.gmane.org> wrote:
>
>> This is the rest of byte-range lock cache patchset that includes several fixes in patches #1 and #3.
>>
>> The patchset is going to simplify brlocking code and add caching support for exclusive oplock cases. I splitted it into several independent parts - so, each can be applied separately once it's reviewed.
>>
>> Any comments and testing are welcome!
>>
>> Pavel Shilovsky (4):
>> CIFS: Implement caching mechanism for mandatory brlocks
>> CIFS: Implement caching mechanism for posix brlocks
>> CIFS: Send as many mandatory unlock ranges at once as possible
>> CIFS: Make cifs_push_locks send as many locks at once as possible
>>
>> fs/cifs/cifsglob.h | 2 +
>> fs/cifs/cifsproto.h | 7 +-
>> fs/cifs/cifssmb.c | 48 +++++-
>> fs/cifs/file.c | 533 ++++++++++++++++++++++++++++++++++++++++++++++-----
>> 4 files changed, 538 insertions(+), 52 deletions(-)
>>
>
> This patchset seems to fix the regression in the earlier one. I've also
> looked over it and don't see any obvious problems. Let's get this
> merged early so it can get the full testing cycle for 3.2.
>
> Acked-by: Jeff Layton <jlayton-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
Thanks for the review!
Steve, can you look at these 4 patches, please?
--
Best regards,
Pavel Shilovsky.
^ permalink raw reply
* [Qemu-devel] [PATCH 0/5] monitor+qxl: async monitor support
From: Alon Levy @ 2011-10-24 12:02 UTC (permalink / raw)
To: lcapitulino, armbru, kraxel; +Cc: mlureau, qemu-devel
This patchset converts the screen_dump command to async across qemu, and then
implements it asynchronously for the qxl device in Native mode. This fixes a
hang that is caused when the spice client is also a qemu monitor client and the
client is single threaded:
io thread worker thread client
<---------------------------------------------------- screendump
do_screen_dump-> read------->
flush, read
client socket------------->
Monitor maintainers: The first patch changes the monitor command to be async.
The rest are qxl changes only.
Alon Levy (5):
monitor: screen_dump async
qxl: s/__FUNCTION__/__func__/, change logging levels
qxl: support concurrent async commands
qxl: split qxl_render_display_resized
qxl: support async monitor screen dump
console.c | 5 +-
console.h | 7 +-
hmp-commands.hx | 3 +-
hw/g364fb.c | 12 ++-
hw/qxl-render.c | 136 ++++++++++++++++++++----------
hw/qxl.c | 236 +++++++++++++++++++++++++++++++++++++--------------
hw/qxl.h | 63 +++++++++++++-
hw/vga.c | 7 +-
hw/vmware_vga.c | 5 +-
monitor.c | 5 +-
qmp-commands.hx | 3 +-
ui/spice-display.c | 19 ++--
ui/spice-display.h | 7 +-
13 files changed, 363 insertions(+), 145 deletions(-)
--
1.7.7
^ permalink raw reply
* Re: [PATCH] staging:iio:events: Make sure userspace buffer is large enough
From: Jonathan Cameron @ 2011-10-24 12:05 UTC (permalink / raw)
To: Lars-Peter Clausen
Cc: Michael Hennerich, linux-iio, device-drivers-devel, drivers
In-Reply-To: <4EA5533E.40703@metafoo.de>
On 10/24/11 12:59, Lars-Peter Clausen wrote:
> On 10/24/2011 01:55 PM, Jonathan Cameron wrote:
>> On 10/24/11 12:52, Lars-Peter Clausen wrote:
>>> Make sure that the userspace buffer is large enough to hold a iio_event_data
>>> struct before writing to it.
>>>
>> Good catch. Shall I tack this on the end of the two fixes sets I sent earlier?
>
> Fine with me. Thanks.
>
Cool, both this and the iio_utils.h one are in the github master branch now
(I'll rebase the others in a sec). I switched to Signed-off-by as they are
passing through my hands. Thanks for these.
Jonathan.
^ permalink raw reply
* Re: [PATCH] ASoC: wm8996: Avoid a redundant i2c_get_clientdata call in wm8996_i2c_remove
From: Girdwood, Liam @ 2011-10-24 12:04 UTC (permalink / raw)
To: Axel Lin; +Cc: linux-kernel, Mark Brown, Dimitris Papastamos, alsa-devel
In-Reply-To: <1319427072.5773.1.camel@phoenix>
On 24 October 2011 04:31, Axel Lin <axel.lin@gmail.com> wrote:
> Signed-off-by: Axel Lin <axel.lin@gmail.com>
> ---
> sound/soc/codecs/wm8996.c | 2 +-
> 1 files changed, 1 insertions(+), 1 deletions(-)
>
> diff --git a/sound/soc/codecs/wm8996.c b/sound/soc/codecs/wm8996.c
> index 645c980..32324c9 100644
> --- a/sound/soc/codecs/wm8996.c
> +++ b/sound/soc/codecs/wm8996.c
> @@ -3144,7 +3144,7 @@ static __devexit int wm8996_i2c_remove(struct i2c_client *client)
> snd_soc_unregister_codec(&client->dev);
> if (wm8996->pdata.ldo_ena > 0)
> gpio_free(wm8996->pdata.ldo_ena);
> - kfree(i2c_get_clientdata(client));
> + kfree(wm8996);
> return 0;
> }
>
Acked-by: Liam Girdwood <lrg@ti.com>
^ permalink raw reply
* Re: [PATCH] ASoC: wm8996: Avoid a redundant i2c_get_clientdata call in wm8996_i2c_remove
From: Girdwood, Liam @ 2011-10-24 12:04 UTC (permalink / raw)
To: Axel Lin; +Cc: Dimitris Papastamos, alsa-devel, Mark Brown, linux-kernel
In-Reply-To: <1319427072.5773.1.camel@phoenix>
On 24 October 2011 04:31, Axel Lin <axel.lin@gmail.com> wrote:
> Signed-off-by: Axel Lin <axel.lin@gmail.com>
> ---
> sound/soc/codecs/wm8996.c | 2 +-
> 1 files changed, 1 insertions(+), 1 deletions(-)
>
> diff --git a/sound/soc/codecs/wm8996.c b/sound/soc/codecs/wm8996.c
> index 645c980..32324c9 100644
> --- a/sound/soc/codecs/wm8996.c
> +++ b/sound/soc/codecs/wm8996.c
> @@ -3144,7 +3144,7 @@ static __devexit int wm8996_i2c_remove(struct i2c_client *client)
> snd_soc_unregister_codec(&client->dev);
> if (wm8996->pdata.ldo_ena > 0)
> gpio_free(wm8996->pdata.ldo_ena);
> - kfree(i2c_get_clientdata(client));
> + kfree(wm8996);
> return 0;
> }
>
Acked-by: Liam Girdwood <lrg@ti.com>
_______________________________________________
Alsa-devel mailing list
Alsa-devel@alsa-project.org
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
^ permalink raw reply
* Re: [PATCH] ASoC: wm8400: Fix setting Fout clock divider for FLL Control 4
From: Girdwood, Liam @ 2011-10-24 12:04 UTC (permalink / raw)
To: Axel Lin; +Cc: linux-kernel, Mark Brown, Dimitris Papastamos, alsa-devel
In-Reply-To: <1319294907.2678.2.camel@phoenix>
On 22 October 2011 15:48, Axel Lin <axel.lin@gmail.com> wrote:
> What we want here is to clear the WM8400_FLL_OUTDIV_MASK bits then
> OR with factors.outdiv.
>
> Signed-off-by: Axel Lin <axel.lin@gmail.com>
> ---
> sound/soc/codecs/wm8400.c | 2 +-
> 1 files changed, 1 insertions(+), 1 deletions(-)
>
> diff --git a/sound/soc/codecs/wm8400.c b/sound/soc/codecs/wm8400.c
> index dc13be2..f29bc26 100644
> --- a/sound/soc/codecs/wm8400.c
> +++ b/sound/soc/codecs/wm8400.c
> @@ -1059,7 +1059,7 @@ static int wm8400_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
> wm8400_write(codec, WM8400_FLL_CONTROL_3, factors.n);
>
> reg = wm8400_read(codec, WM8400_FLL_CONTROL_4);
> - reg &= WM8400_FLL_OUTDIV_MASK;
> + reg &= ~WM8400_FLL_OUTDIV_MASK;
> reg |= factors.outdiv;
> wm8400_write(codec, WM8400_FLL_CONTROL_4, reg);
>
> --
> 1.7.5.4
>
>
>
>
Acked-by: Liam Girdwood <lrg@ti.com>
^ permalink raw reply
* Re: [PATCH] ASoC: wm8400: Fix setting Fout clock divider for FLL Control 4
From: Girdwood, Liam @ 2011-10-24 12:04 UTC (permalink / raw)
To: Axel Lin; +Cc: Dimitris Papastamos, alsa-devel, Mark Brown, linux-kernel
In-Reply-To: <1319294907.2678.2.camel@phoenix>
On 22 October 2011 15:48, Axel Lin <axel.lin@gmail.com> wrote:
> What we want here is to clear the WM8400_FLL_OUTDIV_MASK bits then
> OR with factors.outdiv.
>
> Signed-off-by: Axel Lin <axel.lin@gmail.com>
> ---
> sound/soc/codecs/wm8400.c | 2 +-
> 1 files changed, 1 insertions(+), 1 deletions(-)
>
> diff --git a/sound/soc/codecs/wm8400.c b/sound/soc/codecs/wm8400.c
> index dc13be2..f29bc26 100644
> --- a/sound/soc/codecs/wm8400.c
> +++ b/sound/soc/codecs/wm8400.c
> @@ -1059,7 +1059,7 @@ static int wm8400_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
> wm8400_write(codec, WM8400_FLL_CONTROL_3, factors.n);
>
> reg = wm8400_read(codec, WM8400_FLL_CONTROL_4);
> - reg &= WM8400_FLL_OUTDIV_MASK;
> + reg &= ~WM8400_FLL_OUTDIV_MASK;
> reg |= factors.outdiv;
> wm8400_write(codec, WM8400_FLL_CONTROL_4, reg);
>
> --
> 1.7.5.4
>
>
>
>
Acked-by: Liam Girdwood <lrg@ti.com>
_______________________________________________
Alsa-devel mailing list
Alsa-devel@alsa-project.org
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
^ permalink raw reply
* [PATCH] spi/pl022: Enable clock in probe an use runtime_idle
From: Grant Likely @ 2011-10-24 12:03 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1319206124-17549-1-git-send-email-ulf.hansson@stericsson.com>
On Fri, Oct 21, 2011 at 04:08:44PM +0200, Ulf Hansson wrote:
> Since we are always runtime resumed when leaving probe
> the clock must be enabled. To accomplish that we are able
> to be runtime suspended after probe in the case when no
> request is going to be recieved, a runtime_idle function
> has been implemented.
>
> Change-Id: I6cb86f2cad30ecaab16f512daf4674b039b18213
> Signed-off-by: Ulf Hansson <ulf.hansson@stericsson.com>
> Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/34447
Acked-by: Grant Likely <grant.likely@secretlab.ca>
Since it depends on Russell's tree, I'm okay with it going in that way.
g.
> ---
> drivers/spi/spi-pl022.c | 18 +++++++++++++++++-
> 1 files changed, 17 insertions(+), 1 deletions(-)
>
> diff --git a/drivers/spi/spi-pl022.c b/drivers/spi/spi-pl022.c
> index f103e47..ad48fba 100644
> --- a/drivers/spi/spi-pl022.c
> +++ b/drivers/spi/spi-pl022.c
> @@ -2184,6 +2184,12 @@ pl022_probe(struct amba_device *adev, const struct amba_id *id)
> goto err_clk_prep;
> }
>
> + status = clk_enable(pl022->clk);
> + if (status) {
> + dev_err(&adev->dev, "could not enable SSP/SPI bus clock\n");
> + goto err_no_clk_en;
> + }
> +
> /* Disable SSP */
> writew((readw(SSP_CR1(pl022->virtbase)) & (~SSP_CR1_MASK_SSE)),
> SSP_CR1(pl022->virtbase));
> @@ -2237,6 +2243,8 @@ pl022_probe(struct amba_device *adev, const struct amba_id *id)
>
> free_irq(adev->irq[0], pl022);
> err_no_irq:
> + clk_disable(pl022->clk);
> + err_no_clk_en:
> clk_unprepare(pl022->clk);
> err_clk_prep:
> clk_put(pl022->clk);
> @@ -2342,11 +2350,19 @@ static int pl022_runtime_resume(struct device *dev)
>
> return 0;
> }
> +
> +static int pl022_runtime_idle(struct device *dev)
> +{
> + pm_runtime_suspend(dev);
> + return 0;
> +}
> #endif
>
> static const struct dev_pm_ops pl022_dev_pm_ops = {
> SET_SYSTEM_SLEEP_PM_OPS(pl022_suspend, pl022_resume)
> - SET_RUNTIME_PM_OPS(pl022_runtime_suspend, pl022_runtime_resume, NULL)
> + SET_RUNTIME_PM_OPS(pl022_runtime_suspend,
> + pl022_runtime_resume,
> + pl022_runtime_idle)
> };
>
> static struct vendor_data vendor_arm = {
> --
> 1.7.5.4
>
^ permalink raw reply
* Re: [PATCH] spi/pl022: Enable clock in probe an use runtime_idle
From: Grant Likely @ 2011-10-24 12:03 UTC (permalink / raw)
To: Ulf Hansson; +Cc: spi-devel-general, Lee Jones, linux-arm-kernel
In-Reply-To: <1319206124-17549-1-git-send-email-ulf.hansson@stericsson.com>
On Fri, Oct 21, 2011 at 04:08:44PM +0200, Ulf Hansson wrote:
> Since we are always runtime resumed when leaving probe
> the clock must be enabled. To accomplish that we are able
> to be runtime suspended after probe in the case when no
> request is going to be recieved, a runtime_idle function
> has been implemented.
>
> Change-Id: I6cb86f2cad30ecaab16f512daf4674b039b18213
> Signed-off-by: Ulf Hansson <ulf.hansson@stericsson.com>
> Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/34447
Acked-by: Grant Likely <grant.likely@secretlab.ca>
Since it depends on Russell's tree, I'm okay with it going in that way.
g.
> ---
> drivers/spi/spi-pl022.c | 18 +++++++++++++++++-
> 1 files changed, 17 insertions(+), 1 deletions(-)
>
> diff --git a/drivers/spi/spi-pl022.c b/drivers/spi/spi-pl022.c
> index f103e47..ad48fba 100644
> --- a/drivers/spi/spi-pl022.c
> +++ b/drivers/spi/spi-pl022.c
> @@ -2184,6 +2184,12 @@ pl022_probe(struct amba_device *adev, const struct amba_id *id)
> goto err_clk_prep;
> }
>
> + status = clk_enable(pl022->clk);
> + if (status) {
> + dev_err(&adev->dev, "could not enable SSP/SPI bus clock\n");
> + goto err_no_clk_en;
> + }
> +
> /* Disable SSP */
> writew((readw(SSP_CR1(pl022->virtbase)) & (~SSP_CR1_MASK_SSE)),
> SSP_CR1(pl022->virtbase));
> @@ -2237,6 +2243,8 @@ pl022_probe(struct amba_device *adev, const struct amba_id *id)
>
> free_irq(adev->irq[0], pl022);
> err_no_irq:
> + clk_disable(pl022->clk);
> + err_no_clk_en:
> clk_unprepare(pl022->clk);
> err_clk_prep:
> clk_put(pl022->clk);
> @@ -2342,11 +2350,19 @@ static int pl022_runtime_resume(struct device *dev)
>
> return 0;
> }
> +
> +static int pl022_runtime_idle(struct device *dev)
> +{
> + pm_runtime_suspend(dev);
> + return 0;
> +}
> #endif
>
> static const struct dev_pm_ops pl022_dev_pm_ops = {
> SET_SYSTEM_SLEEP_PM_OPS(pl022_suspend, pl022_resume)
> - SET_RUNTIME_PM_OPS(pl022_runtime_suspend, pl022_runtime_resume, NULL)
> + SET_RUNTIME_PM_OPS(pl022_runtime_suspend,
> + pl022_runtime_resume,
> + pl022_runtime_idle)
> };
>
> static struct vendor_data vendor_arm = {
> --
> 1.7.5.4
>
^ permalink raw reply
* Re: [PATCH tip/core/rcu 22/55] rcu: Add grace-period, quiescent-state, and call_rcu trace events
From: Paul E. McKenney @ 2011-10-24 12:02 UTC (permalink / raw)
To: Josh Triplett
Cc: linux-kernel, mingo, laijs, dipankar, akpm, mathieu.desnoyers,
niv, tglx, peterz, rostedt, Valdis.Kletnieks, dhowells,
eric.dumazet, darren, patches, Paul E. McKenney
In-Reply-To: <20111017013352.GB19421@leaf>
On Sun, Oct 16, 2011 at 06:33:53PM -0700, Josh Triplett wrote:
> On Tue, Sep 06, 2011 at 11:00:16AM -0700, Paul E. McKenney wrote:
> > From: Paul E. McKenney <paul.mckenney@linaro.org>
> >
> > Add trace events to record grace-period start and end, quiescent states,
> > CPUs noticing grace-period start and end, grace-period initialization,
> > call_rcu() invocation, tasks blocking in RCU read-side critical sections,
> > tasks exiting those same critical sections, force_quiescent_state()
> > detection of dyntick-idle and offline CPUs, CPUs entering and leaving
> > dyntick-idle mode (except from NMIs), CPUs coming online and going
> > offline, and CPUs being kicked for staying in dyntick-idle mode for too
> > long (as in many weeks, even on 32-bit systems).
> >
> > Signed-off-by: Paul E. McKenney <paul.mckenney@linaro.org>
> > Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
> >
> > rcu: Add the rcu flavor to callback trace events
> >
> > The earlier trace events for registering RCU callbacks and for invoking
> > them did not include the RCU flavor (rcu_bh, rcu_preempt, or rcu_sched).
> > This commit adds the RCU flavor to those trace events.
> >
> > Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
>
> Did you intend for this commit message to contain two full commit
> messages, and three signoffs from you?
No, messed up a rebase. <red face>
> Also, the subject doesn't seem to cover the second half of the commit
> message.
This is indeed the first set of trace events where the name of the RCU
flavor was important.
Thanx, Paul
^ permalink raw reply
* Re: [Qemu-devel] KVM call agenda for October 25
From: Peter Maydell @ 2011-10-24 12:02 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: qemu-devel, kvm
In-Reply-To: <j83ihr$ec5$1@dough.gmane.org>
On 24 October 2011 12:35, Paolo Bonzini <pbonzini@redhat.com> wrote:
> On 10/24/2011 01:04 PM, Juan Quintela wrote:
>> Please send in any agenda items you are interested in covering.
>
> - What's left to merge for 1.0.
Things on my list, FWIW:
* current target-arm pullreq
* PL041 support (needs another patch round to fix a minor bug
Andrzej spotted)
* cpu_single_env must be thread-local
I also think that it's somewhat unfortunate that we now will
compile on ARM hosts so that we always abort on startup (due
to the reliance on a working makecontext()) but I'm not really
sure how to deal with that one.
-- PMM
^ permalink raw reply
* Re: [PATCH] gpiolib: Provide a definition of struct gpio for the stub gpiolib
From: Grant Likely @ 2011-10-24 12:01 UTC (permalink / raw)
To: Mark Brown; +Cc: Grant Likely, linux-kernel
In-Reply-To: <1319455649-4916-1-git-send-email-broonie@opensource.wolfsonmicro.com>
On Mon, Oct 24, 2011 at 01:27:29PM +0200, Mark Brown wrote:
> This makes the stub gpio_request_array() much more usable as drivers can
> declare struct gpio variables.
>
> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Shouldn't this patch remove the definition from
include/asm-generic/gpio.h at the same time?
g.
> ---
> include/linux/gpio.h | 7 ++++++-
> 1 files changed, 6 insertions(+), 1 deletions(-)
>
> diff --git a/include/linux/gpio.h b/include/linux/gpio.h
> index 17b5a0d..e885103 100644
> --- a/include/linux/gpio.h
> +++ b/include/linux/gpio.h
> @@ -24,7 +24,6 @@
> #include <linux/errno.h>
>
> struct device;
> -struct gpio;
> struct gpio_chip;
>
> /*
> @@ -36,6 +35,12 @@ struct gpio_chip;
> * warning when something is wrongly called.
> */
>
> +struct gpio {
> + unsigned gpio;
> + unsigned long flags;
> + const char *label;
> +};
> +
> static inline bool gpio_is_valid(int number)
> {
> return false;
> --
> 1.7.6.3
>
^ permalink raw reply
* Re: [Xenomai-core] some problems with interrupts
From: Gilles Chanteperdrix @ 2011-10-24 12:01 UTC (permalink / raw)
To: Roberto Bielli; +Cc: xenomai
In-Reply-To: <4EA53A99.1050305@domain.hid>
On 10/24/2011 12:14 PM, Roberto Bielli wrote:
> Hi,
>
> i installed the patch 'adeos-ipipe-2.6.31-arm-1.16-02.patch' on a kernel
> 2.6.31 for imx257 processor.
> I have a xenomai complex application that read touchscreen events with
> tslib when pressed.
> In the kernel log i try these lines: ( the read job is made in a
> not-realtime thread )
>
> ------------[ cut here ]------------
> WARNING: at drivers/input/touchscreen/mxc_tsc.c:599
> mxc_tsc_interrupt+0x19c/0x30c [mxc_tsc]()
> (...)
>
> Do you know the meaning in xenomai of this error (so i can modify
> something to resolve the problem )?
This looks more like a warning than an error. At first glance, it has
nothing to do with xenomai. Besides, you seem not to be using a mainline
version of the kernel, because in the versions I have, there is no
drivers/input/touchscreen/mxc_tsc.c, so, it is hard for me to debug this
issue.
What has file drivers/input/touchscreen/mxc_tsc.c on line 599?
You may want to try a more recent version, as linux 2.6.31 starts being
seriously outdated.
--
Gilles.
^ permalink raw reply
* Re: [RFC] mac80211: Fix STA supported rate configuration with dummy entry
From: Arik Nemtsov @ 2011-10-24 11:59 UTC (permalink / raw)
To: Jouni Malinen; +Cc: Johannes Berg, Felix Fietkau, linux-wireless
In-Reply-To: <20111023194059.GA18385@jm.kir.nu>
On Sun, Oct 23, 2011 at 21:40, Jouni Malinen <j@w1.fi> wrote:
>
> Are all rate control algorithms fine with the second
> rate_control_rate_init() call? That is needed in the TDLS use case where
> the supported rate set is known only after the STA entry has been
Note that the sta-rates are not really required before second addition
(which also sets them). Initially the STA is not authorized for direct
Tx (as determined by the WLAN_STA_TDLS_PEER_AUTH bit).
We don't expect direct frames during link setup.
> added. I guess it would be possible to delay addition of the STA entry
> for TDLS until the supported rates are known, but I did not look at the
> details on what exactly that would require.
The STA is added to let us know we should drop all non-setup packets
between TDLS peers currently in link setup. We could have used a
different indication, but the STA entry is make the most sense here
since it is automatically cleaned up when we are disconnected from the
AP (as all TDLS state should be).
How about this one instead (tested hwsim with it):
>From d8b7acc16073e50f4fda3365d98ad01b21e2c631 Mon Sep 17 00:00:00 2001
From: Arik Nemtsov <arik@wizery.com>
Date: Mon, 24 Oct 2011 13:44:07 +0200
Subject: [RFC] mac80211: init rate-control for TDLS sta when supp-rates are
known
Initialize rate control algorithms only when supported rates are known
for a TDLS peer sta. Direct Tx between peers is not allowed before the
link is enabled. In turn, this only occurs after a change_station()
call that sets supported rates.
---
net/mac80211/cfg.c | 10 +++++++++-
1 files changed, 9 insertions(+), 1 deletions(-)
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 1309bb9..9f05416d 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -829,7 +829,12 @@ static int ieee80211_add_station(struct wiphy
*wiphy, struct net_device *dev,
sdata->vif.type == NL80211_IFTYPE_STATION))
return -ENOTSUPP;
- rate_control_rate_init(sta);
+ /*
+ * for TDLS, rate control should be initialized only when supported
+ * rates are known.
+ */
+ if (!test_sta_flag(sta, WLAN_STA_TDLS_PEER))
+ rate_control_rate_init(sta);
layer2_update = sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
sdata->vif.type == NL80211_IFTYPE_AP;
@@ -913,6 +918,9 @@ static int ieee80211_change_station(struct wiphy *wiphy,
sta_apply_parameters(local, sta, params);
+ if (test_sta_flag(sta, WLAN_STA_TDLS_PEER) && params->supported_rates)
+ rate_control_rate_init(sta);
+
rcu_read_unlock();
if (sdata->vif.type == NL80211_IFTYPE_STATION &&
--
1.7.5.4
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.