All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] megasas: Usage of is_write in megasas_map_sgl()
@ 2010-12-02 22:24 Nicholas A. Bellinger
  2010-12-03 10:25 ` [Qemu-devel] " Kevin Wolf
  0 siblings, 1 reply; 3+ messages in thread
From: Nicholas A. Bellinger @ 2010-12-02 22:24 UTC (permalink / raw)
  To: qemu-devel
  Cc: Kevin Wolf, Stefan Hajnoczi, Hannes Reinecke, Paolo Bonzini,
	Christoph Hellwig, Gerd Hoffmann

Hi Hannes and Co,

I had a quick question wrt to megassas_map_sgl() ->
cpu_physical_memory_map() and usage of the 'is_write' parameter.

In megasas.v3 code on v0.13.0, this appears as:

static int megasas_map_sgl(struct megasas_cmd_t *cmd, int pa_offset)
{
    int i;
    uint16_t flags = le16_to_cpu(cmd->frame->header.flags);
    int is_sgl64 = (flags & MFI_FRAME_SGL64) ? 1 : 0;
    int is_write = (flags & MFI_FRAME_DIR_WRITE) ? 1 : 0;
    int sgl_addr_size = is_sgl64 ? sizeof(uint64_t) : sizeof(uint32_t);
    size_t iov_count = 0;

    cmd->iov = qemu_mallocz(sizeof(struct iovec) * (cmd->frame->header.sge_count + 1));
    for (i = 0; i < cmd->frame->header.sge_count; i++) {
        target_phys_addr_t pa, iov_pa, iov_size;

        pa = cmd->pa + pa_offset;
        if (is_sgl64)
            iov_pa = ldq_phys(pa);
        else
            iov_pa = ldl_phys(pa);
        iov_size = ldl_phys(pa + sgl_addr_size);
        DPRINTF_IO("iov_pa: %lx iov_size: %d, is_write: %d\n", iov_pa, (int)iov_size, is_write);
        cmd->iov[i].iov_base = cpu_physical_memory_map(iov_pa, &iov_size, is_write);
        cmd->iov[i].iov_len = iov_size;
        pa_offset += sgl_addr_size + sizeof(uint32_t);
        iov_count += iov_size;
    }

    <SNIP>

which I believe is following incoming SCSI CDB WRITE/READ
classification, right..?  So for cpu_physical_memory_map() with the
initial 16-byte INQUIRY with the lastest code, this is set to
is_write=0..

Looking at v0.12.5 code, the is_write is inverted in it's equivilent
form inside hw/scsi-generic.c:scsi_generic_map() using the QEMUSGList
that is being setup in the working version megasas_map_sgl():

static void megasas_map_sgl(struct megasas_cmd_t *cmd, int pa_offset)
{
    int i;
    int is_sgl64 = (cmd->frame->header.flags & MFI_FRAME_SGL64) ? 1 : 0;
    int sgl_addr_size = is_sgl64 ? sizeof(uint64_t) : sizeof(uint32_t);

    qemu_sglist_init(&cmd->sg, cmd->frame->header.sge_count);
    for (i = 0; i < cmd->frame->header.sge_count; i++) {
        target_phys_addr_t pa, iov_pa;

        pa = cmd->pa + pa_offset;
        if (is_sgl64)
            iov_pa = ldq_phys(pa);
        else
            iov_pa = ldl_phys(pa);
        qemu_sglist_add(&cmd->sg, iov_pa, ldl_phys(pa + sgl_addr_size));
        pa_offset += sgl_addr_size + sizeof(uint32_t);
    }
}

to scsi_req_sgl() -> scsi-generic.c:scsi_generic_req_sgl() to down
to scsi_generic_map and the inverted is_write:

static int scsi_generic_map(SCSIGenericReq *r, QEMUSGList *sg)
{
    int is_write = !scsi_req_is_write(&r->req);
    target_phys_addr_t cur_addr, cur_len, cur_offset = 0;
    void *mem;
    int i;

    qemu_iovec_reset(&r->iov);
    for (i = 0; i < sg->nsg;) {
        cur_addr = sg->sg[i].base + cur_offset;
        cur_len = sg->sg[i].len - cur_offset;
        DPRINTF("Using cur_addr: 0x%016lx cur_len: 0x%016lx\n", cur_addr, cur_len);

        mem = cpu_physical_memory_map(cur_addr, &cur_len, is_write);
        if (!mem)
            goto err;

        DPRINTF("Adding iovec for mem: %p len: 0x%016lx\n", mem, cur_len);
        qemu_iovec_add(&r->iov, mem, cur_len);
        cur_offset += cur_len;
        if (cur_offset == sg->sg[i].len) {
            cur_offset = 0;
            i++;
        }
    }
    return 0;

    <SNIP>

and here the first 16-byte INQUIRY appears as is_write=1..

The usage of a inverted is_write with cpu_physical_memory_map() also
seems to be the case in dma-helpers.c:dma_brdv_cb():

	mem = cpu_physical_memory_map(cur_addr, &cur_len, !dbs->is_write);

After changing to an inverted is_write in megasas.v3/megasas-upstream-v1
code, this still does *not* seem to make a difference wrt to the 64-bit
Win7 case, and the same BSOD appears..  In any event, we should verify
this with QEMU folks in terms of what the proper usage of is_write for
cpu_physical_memory_map().  Gerd and Kevin comments here..?

I am also wondering if Gerd's original v0.12.5 SCSI rewrite with
the following logic could be having a subtle affect:

*) megasas_map_sgl() being split up into a QEMUSGList at cmd->sg and
   down to cpu_physical_memory_map() -> qemu_iovec_add(&r->iov, ...)

instead of the new:

*) megasas_map_sgl() using a freshly qemu_malloc()'s cmd->iov buffer
   down to cpu_physical_memory_map() for cmd->iov[i].base, and not using
   an QEMUSGList intermediary.

AFAICT this does not seem to be an issue (not tested with a patch yet),
but wanted to double check that the usage of ld*_phys() for iov_pa and
iov_size directly preceeding cpu_physical_memory_map() is OK in
megasas.v3, and that skipping the QEMUSGList part of the mapping from
megasas_cmd->pa to megas_cmd->sg in v0.12.5 code is not creating some
subtle effect to break some guests..?

Any thoughts guys..?

--nab

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

* [Qemu-devel] Re: megasas: Usage of is_write in megasas_map_sgl()
  2010-12-02 22:24 [Qemu-devel] megasas: Usage of is_write in megasas_map_sgl() Nicholas A. Bellinger
@ 2010-12-03 10:25 ` Kevin Wolf
  2010-12-03 10:42   ` Hannes Reinecke
  0 siblings, 1 reply; 3+ messages in thread
From: Kevin Wolf @ 2010-12-03 10:25 UTC (permalink / raw)
  To: Nicholas A. Bellinger
  Cc: Stefan Hajnoczi, qemu-devel, Gerd Hoffmann, Paolo Bonzini,
	Christoph Hellwig, Hannes Reinecke

Am 02.12.2010 23:24, schrieb Nicholas A. Bellinger:
> The usage of a inverted is_write with cpu_physical_memory_map() also
> seems to be the case in dma-helpers.c:dma_brdv_cb():
> 
> 	mem = cpu_physical_memory_map(cur_addr, &cur_len, !dbs->is_write);
>
> After changing to an inverted is_write in megasas.v3/megasas-upstream-v1
> code, this still does *not* seem to make a difference wrt to the 64-bit
> Win7 case, and the same BSOD appears..  In any event, we should verify
> this with QEMU folks in terms of what the proper usage of is_write for
> cpu_physical_memory_map().  Gerd and Kevin comments here..?

I haven't looked at the SCSI code, but the dma-helpers.c one is easy to
explain: If you read from the disk, you write to memory.

Kevin

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

* [Qemu-devel] Re: megasas: Usage of is_write in megasas_map_sgl()
  2010-12-03 10:25 ` [Qemu-devel] " Kevin Wolf
@ 2010-12-03 10:42   ` Hannes Reinecke
  0 siblings, 0 replies; 3+ messages in thread
From: Hannes Reinecke @ 2010-12-03 10:42 UTC (permalink / raw)
  To: Kevin Wolf
  Cc: Stefan Hajnoczi, qemu-devel, Nicholas A. Bellinger,
	Gerd Hoffmann, Paolo Bonzini, Christoph Hellwig

On 12/03/2010 11:25 AM, Kevin Wolf wrote:
> Am 02.12.2010 23:24, schrieb Nicholas A. Bellinger:
>> The usage of a inverted is_write with cpu_physical_memory_map() also
>> seems to be the case in dma-helpers.c:dma_brdv_cb():
>>
>> 	mem = cpu_physical_memory_map(cur_addr, &cur_len, !dbs->is_write);
>>
>> After changing to an inverted is_write in megasas.v3/megasas-upstream-v1
>> code, this still does *not* seem to make a difference wrt to the 64-bit
>> Win7 case, and the same BSOD appears..  In any event, we should verify
>> this with QEMU folks in terms of what the proper usage of is_write for
>> cpu_physical_memory_map().  Gerd and Kevin comments here..?
> 
> I haven't looked at the SCSI code, but the dma-helpers.c one is easy to
> explain: If you read from the disk, you write to memory.
> 
But the main point here is: When should we set the 'is_write' parameter?
Both reading and writing will go into memory, so from that point we
always would need to set this ...

And some documentation about this parameter would be really beneficial.

Cheers,

Hannes

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

end of thread, other threads:[~2010-12-03 10:41 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-12-02 22:24 [Qemu-devel] megasas: Usage of is_write in megasas_map_sgl() Nicholas A. Bellinger
2010-12-03 10:25 ` [Qemu-devel] " Kevin Wolf
2010-12-03 10:42   ` Hannes Reinecke

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.