bug-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Interface for SCSI transactions ?


From: Thomas Schmitt
Subject: Re: Interface for SCSI transactions ?
Date: Fri, 23 Sep 2011 22:33:58 +0200

Hi,

i began to sketch serialization from struct to byte array.

Important question:

Am i allowed to make the RPC ugly if it reduces system load ?


There seems to be an inavoidable performance penalty with my naive
idea to allow an arbitrary reversible transformation from struct
to byte array.
In this case i have to copy the possibly fat payload buffer more often
than i would have to if i get it separately and without need for
conversion.

Separate payload buffers would yield a bloated RPC definition and
C function prototype, i fear:

  routine device_transact_native(
             device          : device_t;
       in    function_code   : unsigned int;
       in    in_ctrl         : ^ array[] of unsigned char;
       in    in_data         : ^ array[] of unsigned char;
       out   out_ctrl        : ^ array[] of unsigned char;
       out   out_data        : ^ array[] of unsigned char
       );

with this RPC receiver in the kernel, resp. the method of
struct device_emulation_ops:

  io_return_t
  ds_device_transact_native (device_t dev, unsigned int function_code,
                             unsigned char *in_ctrl,
                             mach_msg_type_number_t in_ctrl_len,
                             unsigned char *in_data,
                             mach_msg_type_number_t in_data_len,
                             unsigned char *out_ctrl,
                             mach_msg_type_number_t *out_ctrl_len,
                             unsigned char *out_data,
                             mach_msg_type_number_t *out_data_len);

Rationale:

To put the big buffers in_data and out_data into the structs would be
very inconvenient on their respective receiver sides. One would have to
copy them or hold the serialized byte array alive as long as the buffer
is needed.
This might be doable on the kernel side, but on the userland side
one will sooner or later be forced to copy the bytes out of the struct.

The classical solution to avoid such need for copying is the C gesture 

  struct ctrl {

    ... some other fields ...

    unsigned char *data; /* externally provided storage which can be handed
                            over in userland by pointer without copying */
  }

All examined SCSI transaction structs of other OSes do it that way.
Hurd would be inferior if it would be forced to do intermediately
  struct ctrl {
    ...
    unsigned char data[65336]; /* lives and dies with (serialized) ctrl */
  }
  
The lack of structure in MIG lets me see only this equivalent for above
storage pointer:
  
  ctrl         : ^ array[] of unsigned char;
  data         : ^ array[] of unsigned char

I want to strictly keep apart in and out parameters to avoid unnecessary
data transmission through RPC.
So i finally need

       in    in_ctrl         : ^ array[] of unsigned char;
       in    in_data         : ^ array[] of unsigned char;
       out   out_ctrl        : ^ array[] of unsigned char;
       out   out_data        : ^ array[] of unsigned char

which due to the variable array lengths inflates to eight parameters
of the C functions on both sides.


Have a nice day :)

Thomas




reply via email to

[Prev in Thread] Current Thread [Next in Thread]