diff mbox

[v2,02/15] crypto: introduce crypto queue handler

Message ID 1473738741-220600-3-git-send-email-arei.gonglei@huawei.com (mailing list archive)
State New, archived
Headers show

Commit Message

Gonglei (Arei) Sept. 13, 2016, 3:52 a.m. UTC
crypto queue is a gallery used for executing crypto
operation, which supports both synchronization and
asynchronization. The thoughts stolen from net/queue.c

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
---
 crypto/Makefile.objs          |   1 +
 crypto/crypto-queue.c         | 206 ++++++++++++++++++++++++++++++++++++++++++
 crypto/crypto.c               |  28 ++++++
 include/crypto/crypto-queue.h |  69 ++++++++++++++
 include/crypto/crypto.h       |  12 +++
 5 files changed, 316 insertions(+)
 create mode 100644 crypto/crypto-queue.c
 create mode 100644 include/crypto/crypto-queue.h

Comments

Daniel P. Berrangé Sept. 13, 2016, 9:20 a.m. UTC | #1
On Tue, Sep 13, 2016 at 11:52:08AM +0800, Gonglei wrote:
> crypto queue is a gallery used for executing crypto
> operation, which supports both synchronization and
> asynchronization. The thoughts stolen from net/queue.c
> 
> Signed-off-by: Gonglei <arei.gonglei@huawei.com>
> ---
>  crypto/Makefile.objs          |   1 +
>  crypto/crypto-queue.c         | 206 ++++++++++++++++++++++++++++++++++++++++++
>  crypto/crypto.c               |  28 ++++++
>  include/crypto/crypto-queue.h |  69 ++++++++++++++
>  include/crypto/crypto.h       |  12 +++
>  5 files changed, 316 insertions(+)
>  create mode 100644 crypto/crypto-queue.c
>  create mode 100644 include/crypto/crypto-queue.h
> 

> diff --git a/include/crypto/crypto-queue.h b/include/crypto/crypto-queue.h
> new file mode 100644
> index 0000000..6fba64d
> --- /dev/null
> +++ b/include/crypto/crypto-queue.h
> @@ -0,0 +1,69 @@
> +/*
> + * Copyright (c) 2003-2008 Fabrice Bellard
> + * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD.
> + *
> + * Authors:
> + *    Gonglei <arei.gonglei@huawei.com>
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a copy
> + * of this software and associated documentation files (the "Software"), to deal
> + * in the Software without restriction, including without limitation the rights
> + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
> + * copies of the Software, and to permit persons to whom the Software is
> + * furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice shall be included in
> + * all copies or substantial portions of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
> + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
> + * THE SOFTWARE.
> + */

Again, wrong license header.

> +#ifndef QEMU_CRYPTO_QUEUE_H
> +#define QEMU_CRYPTO_QUEUE_H
> +
> +#include "qemu-common.h"
> +
> +typedef struct CryptoPacket CryptoPacket;
> +typedef struct CryptoQueue CryptoQueue;
> +typedef struct CryptoPacketBuf CryptoPacketBuf;
> +
> +typedef void (CryptoPacketSent) (CryptoClientState *, int);

As previously, I'd expect naming of

 QCryptoCryptodevPacket
 QCryptoCryptodevPacketBuf
 QCryptoCryptodevQueue

> +
> +
> +/* Returns:
> + *   >0 - success
> + *    0 - queue packet for future redelivery
> + *   <0 - failure (discard packet)
> + */
> +typedef int (CryptoQueueDeliverFunc)(CryptoClientState *sender,
> +                                     unsigned flags,
> +                                     void *header_opaque,
> +                                     void *opaque);
> +
> +CryptoQueue *
> +qemu_new_crypto_queue(CryptoQueueDeliverFunc *deliver, void *opaque);
> +
> +void qemu_crypto_queue_cache(CryptoQueue *queue,
> +                               unsigned flags,
> +                               CryptoClientState *sender,
> +                               void *opaque,
> +                               CryptoPacketSent *sent_cb);
> +
> +void qemu_del_crypto_queue(CryptoQueue *queue);
> +
> +int qemu_crypto_queue_send(CryptoQueue *queue,
> +                                unsigned flags,
> +                                CryptoClientState *sender,
> +                                void *opaque,
> +                                CryptoPacketSent *sent_cb);
> +
> +void qemu_crypto_queue_purge(CryptoQueue *queue, CryptoClientState *from);
> +bool qemu_crypto_queue_flush(CryptoQueue *queue);

And naming of

  qcrypto_cryptodev_queue_purge
  qcrypto_cryptodev_queue_flush
  etc.

Also missing docs for this file

> +#endif /* QEMU_CRYPTO_QUEUE_H */
> diff --git a/include/crypto/crypto.h b/include/crypto/crypto.h
> index f93f6f9..46b3b9e 100644
> --- a/include/crypto/crypto.h
> +++ b/include/crypto/crypto.h
> @@ -29,6 +29,8 @@
>  
>  #include "qemu/queue.h"
>  #include "qapi-types.h"
> +#include "crypto/crypto-queue.h"
> +
>  
>  typedef void (CryptoPoll)(CryptoClientState *, bool);
>  typedef void (CryptoCleanup) (CryptoClientState *);
> @@ -52,6 +54,8 @@ struct CryptoClientState {
>      char *model;
>      char *name;
>      char info_str[256];
> +    CryptoQueue *incoming_queue;
> +    unsigned int queue_index;
>      CryptoClientDestructor *destructor;
>  };
>  
> @@ -62,5 +66,13 @@ CryptoClientState *new_crypto_client(CryptoClientInfo *info,
>                                      CryptoClientState *peer,
>                                      const char *model,
>                                      const char *name);
> +int qemu_deliver_crypto_packet(CryptoClientState *sender,
> +                              unsigned flags,
> +                              void *header_opqaue,
> +                              void *opaque);
> +int qemu_send_crypto_packet_async(CryptoClientState *sender,
> +                                unsigned flags,
> +                                void *opaque,
> +                                CryptoPacketSent *sent_cb);

Missing docs for these API additions.


Regards,
Daniel
Gonglei (Arei) Sept. 13, 2016, 9:58 a.m. UTC | #2
Hi,

All comments are accepted :)


Regards,
-Gonglei


> -----Original Message-----

> From: Daniel P. Berrange [mailto:berrange@redhat.com]

> Sent: Tuesday, September 13, 2016 5:21 PM

> To: Gonglei (Arei)

> Cc: qemu-devel@nongnu.org; virtio-dev@lists.oasis-open.org; Huangpeng

> (Peter); Luonengjun; mst@redhat.com; stefanha@redhat.com;

> pbonzini@redhat.com; Huangweidong (C); mike.caraman@nxp.com;

> agraf@suse.de; xin.zeng@intel.com; Claudio Fontana; nmorey@kalray.eu;

> vincent.jardin@6wind.com

> Subject: Re: [PATCH v2 02/15] crypto: introduce crypto queue handler

> 

> On Tue, Sep 13, 2016 at 11:52:08AM +0800, Gonglei wrote:

> > crypto queue is a gallery used for executing crypto

> > operation, which supports both synchronization and

> > asynchronization. The thoughts stolen from net/queue.c

> >

> > Signed-off-by: Gonglei <arei.gonglei@huawei.com>

> > ---

> >  crypto/Makefile.objs          |   1 +

> >  crypto/crypto-queue.c         | 206

> ++++++++++++++++++++++++++++++++++++++++++

> >  crypto/crypto.c               |  28 ++++++

> >  include/crypto/crypto-queue.h |  69 ++++++++++++++

> >  include/crypto/crypto.h       |  12 +++

> >  5 files changed, 316 insertions(+)

> >  create mode 100644 crypto/crypto-queue.c

> >  create mode 100644 include/crypto/crypto-queue.h

> >

> 

> > diff --git a/include/crypto/crypto-queue.h b/include/crypto/crypto-queue.h

> > new file mode 100644

> > index 0000000..6fba64d

> > --- /dev/null

> > +++ b/include/crypto/crypto-queue.h

> > @@ -0,0 +1,69 @@

> > +/*

> > + * Copyright (c) 2003-2008 Fabrice Bellard

> > + * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD.

> > + *

> > + * Authors:

> > + *    Gonglei <arei.gonglei@huawei.com>

> > + *

> > + * Permission is hereby granted, free of charge, to any person obtaining a

> copy

> > + * of this software and associated documentation files (the "Software"), to

> deal

> > + * in the Software without restriction, including without limitation the rights

> > + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell

> > + * copies of the Software, and to permit persons to whom the Software is

> > + * furnished to do so, subject to the following conditions:

> > + *

> > + * The above copyright notice and this permission notice shall be included in

> > + * all copies or substantial portions of the Software.

> > + *

> > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,

> EXPRESS OR

> > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF

> MERCHANTABILITY,

> > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO

> EVENT SHALL

> > + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,

> DAMAGES OR OTHER

> > + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,

> ARISING FROM,

> > + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR

> OTHER DEALINGS IN

> > + * THE SOFTWARE.

> > + */

> 

> Again, wrong license header.

> 

> > +#ifndef QEMU_CRYPTO_QUEUE_H

> > +#define QEMU_CRYPTO_QUEUE_H

> > +

> > +#include "qemu-common.h"

> > +

> > +typedef struct CryptoPacket CryptoPacket;

> > +typedef struct CryptoQueue CryptoQueue;

> > +typedef struct CryptoPacketBuf CryptoPacketBuf;

> > +

> > +typedef void (CryptoPacketSent) (CryptoClientState *, int);

> 

> As previously, I'd expect naming of

> 

>  QCryptoCryptodevPacket

>  QCryptoCryptodevPacketBuf

>  QCryptoCryptodevQueue

> 

> > +

> > +

> > +/* Returns:

> > + *   >0 - success

> > + *    0 - queue packet for future redelivery

> > + *   <0 - failure (discard packet)

> > + */

> > +typedef int (CryptoQueueDeliverFunc)(CryptoClientState *sender,

> > +                                     unsigned flags,

> > +                                     void *header_opaque,

> > +                                     void *opaque);

> > +

> > +CryptoQueue *

> > +qemu_new_crypto_queue(CryptoQueueDeliverFunc *deliver, void *opaque);

> > +

> > +void qemu_crypto_queue_cache(CryptoQueue *queue,

> > +                               unsigned flags,

> > +                               CryptoClientState *sender,

> > +                               void *opaque,

> > +                               CryptoPacketSent *sent_cb);

> > +

> > +void qemu_del_crypto_queue(CryptoQueue *queue);

> > +

> > +int qemu_crypto_queue_send(CryptoQueue *queue,

> > +                                unsigned flags,

> > +                                CryptoClientState *sender,

> > +                                void *opaque,

> > +                                CryptoPacketSent *sent_cb);

> > +

> > +void qemu_crypto_queue_purge(CryptoQueue *queue, CryptoClientState

> *from);

> > +bool qemu_crypto_queue_flush(CryptoQueue *queue);

> 

> And naming of

> 

>   qcrypto_cryptodev_queue_purge

>   qcrypto_cryptodev_queue_flush

>   etc.

> 

> Also missing docs for this file

> 

> > +#endif /* QEMU_CRYPTO_QUEUE_H */

> > diff --git a/include/crypto/crypto.h b/include/crypto/crypto.h

> > index f93f6f9..46b3b9e 100644

> > --- a/include/crypto/crypto.h

> > +++ b/include/crypto/crypto.h

> > @@ -29,6 +29,8 @@

> >

> >  #include "qemu/queue.h"

> >  #include "qapi-types.h"

> > +#include "crypto/crypto-queue.h"

> > +

> >

> >  typedef void (CryptoPoll)(CryptoClientState *, bool);

> >  typedef void (CryptoCleanup) (CryptoClientState *);

> > @@ -52,6 +54,8 @@ struct CryptoClientState {

> >      char *model;

> >      char *name;

> >      char info_str[256];

> > +    CryptoQueue *incoming_queue;

> > +    unsigned int queue_index;

> >      CryptoClientDestructor *destructor;

> >  };

> >

> > @@ -62,5 +66,13 @@ CryptoClientState

> *new_crypto_client(CryptoClientInfo *info,

> >                                      CryptoClientState *peer,

> >                                      const char *model,

> >                                      const char *name);

> > +int qemu_deliver_crypto_packet(CryptoClientState *sender,

> > +                              unsigned flags,

> > +                              void *header_opqaue,

> > +                              void *opaque);

> > +int qemu_send_crypto_packet_async(CryptoClientState *sender,

> > +                                unsigned flags,

> > +                                void *opaque,

> > +                                CryptoPacketSent *sent_cb);

> 

> Missing docs for these API additions.

> 

> 

> Regards,

> Daniel

> --

> |: http://berrange.com      -o-

> http://www.flickr.com/photos/dberrange/ :|

> |: http://libvirt.org              -o-

> http://virt-manager.org :|

> |: http://autobuild.org       -o-

> http://search.cpan.org/~danberr/ :|

> |: http://entangle-photo.org       -o-

> http://live.gnome.org/gtk-vnc :|
Paolo Bonzini Sept. 13, 2016, 10:58 a.m. UTC | #3
On 13/09/2016 11:20, Daniel P. Berrange wrote:
>> > +typedef struct CryptoPacket CryptoPacket;
>> > +typedef struct CryptoQueue CryptoQueue;
>> > +typedef struct CryptoPacketBuf CryptoPacketBuf;
>> > +
>> > +typedef void (CryptoPacketSent) (CryptoClientState *, int);
> As previously, I'd expect naming of
> 
>  QCryptoCryptodevPacket
>  QCryptoCryptodevPacketBuf
>  QCryptoCryptodevQueue
> 

Gonglei,

you are copying a lot of code from network backends.

I am not sure why you would need a queue for virtio-crypto rather than a
direct connection between frontend and backend (and the backend would be
QEMU crypto APIs, like Daniel suggested).

Paolo
Ola Liljedahl Sept. 13, 2016, 11:52 a.m. UTC | #4
On 13/09/2016, 12:58, "virtio-dev@lists.oasis-open.org on behalf of Paolo
Bonzini" <virtio-dev@lists.oasis-open.org on behalf of
pbonzini@redhat.com> wrote:

>
>
>On 13/09/2016 11:20, Daniel P. Berrange wrote:
>>> > +typedef struct CryptoPacket CryptoPacket;
>>> > +typedef struct CryptoQueue CryptoQueue;
>>> > +typedef struct CryptoPacketBuf CryptoPacketBuf;
>>> > +
>>> > +typedef void (CryptoPacketSent) (CryptoClientState *, int);
>> As previously, I'd expect naming of
>>
>>  QCryptoCryptodevPacket
>>  QCryptoCryptodevPacketBuf
>>  QCryptoCryptodevQueue
>>
>
>Gonglei,
>
>you are copying a lot of code from network backends.
>
>I am not sure why you would need a queue for virtio-crypto rather than a
>direct connection between frontend and backend (and the backend would be
>QEMU crypto APIs, like Daniel suggested).
What about backends implemented directly in HW? Bypass the middle man.
Make crypto offload meaningful for small size blocks.

‹ Ola

>
>Paolo
>
>---------------------------------------------------------------------
>To unsubscribe, e-mail: virtio-dev-unsubscribe@lists.oasis-open.org
>For additional commands, e-mail: virtio-dev-help@lists.oasis-open.org
>

IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.
Gonglei (Arei) Sept. 14, 2016, 1:03 a.m. UTC | #5
Hi Paolo,


> -----Original Message-----

> From: virtio-dev@lists.oasis-open.org [mailto:virtio-dev@lists.oasis-open.org]

> On Behalf Of Paolo Bonzini

> Sent: Tuesday, September 13, 2016 6:58 PM

> To: Daniel P. Berrange; Gonglei (Arei)

> Cc: qemu-devel@nongnu.org; virtio-dev@lists.oasis-open.org; Huangpeng

> (Peter); Luonengjun; mst@redhat.com; stefanha@redhat.com; Huangweidong

> (C); mike.caraman@nxp.com; agraf@suse.de; xin.zeng@intel.com; Claudio

> Fontana; nmorey@kalray.eu; vincent.jardin@6wind.com

> Subject: [virtio-dev] Re: [PATCH v2 02/15] crypto: introduce crypto queue

> handler

> 

> 

> 

> On 13/09/2016 11:20, Daniel P. Berrange wrote:

> >> > +typedef struct CryptoPacket CryptoPacket;

> >> > +typedef struct CryptoQueue CryptoQueue;

> >> > +typedef struct CryptoPacketBuf CryptoPacketBuf;

> >> > +

> >> > +typedef void (CryptoPacketSent) (CryptoClientState *, int);

> > As previously, I'd expect naming of

> >

> >  QCryptoCryptodevPacket

> >  QCryptoCryptodevPacketBuf

> >  QCryptoCryptodevQueue

> >

> 

> Gonglei,

> 

> you are copying a lot of code from network backends.

> 

> I am not sure why you would need a queue for virtio-crypto rather than a

> direct connection between frontend and backend (and the backend would be

> QEMU crypto APIs, like Daniel suggested).

> 

My initial idea is support asynchronous crypto operation, so I used a queue to
cache the crypto packets like network did. Now I think again, either synchronous or asynchronous
operation is directly depend on the backend cryptodevs' capacity, we don't need
to use a queue to do that, but provide interfaces which include sync and async operations.

I'll drop the middle queue stuff. Thanks!

Regards,
-Gonglei

> Paolo

> 

> ---------------------------------------------------------------------

> To unsubscribe, e-mail: virtio-dev-unsubscribe@lists.oasis-open.org

> For additional commands, e-mail: virtio-dev-help@lists.oasis-open.org
Gonglei (Arei) Sept. 14, 2016, 1:07 a.m. UTC | #6
Hi Ola,



> -----Original Message-----
> From: Ola Liljedahl [mailto:Ola.Liljedahl@arm.com]
> Sent: Tuesday, September 13, 2016 7:53 PM
> To: Paolo Bonzini; Daniel P. Berrange; Gonglei (Arei)
> Cc: qemu-devel@nongnu.org; virtio-dev@lists.oasis-open.org; Huangpeng
> (Peter); Luonengjun; mst@redhat.com; stefanha@redhat.com; Huangweidong
> (C); mike.caraman@nxp.com; agraf@suse.de; xin.zeng@intel.com; Claudio
> Fontana; nmorey@kalray.eu; vincent.jardin@6wind.com
> Subject: Re: [virtio-dev] Re: [PATCH v2 02/15] crypto: introduce crypto queue
> handler
> 
> 
> 
> 
> 
> On 13/09/2016, 12:58, "virtio-dev@lists.oasis-open.org on behalf of Paolo
> Bonzini" <virtio-dev@lists.oasis-open.org on behalf of
> pbonzini@redhat.com> wrote:
> 
> >
> >
> >On 13/09/2016 11:20, Daniel P. Berrange wrote:
> >>> > +typedef struct CryptoPacket CryptoPacket;
> >>> > +typedef struct CryptoQueue CryptoQueue;
> >>> > +typedef struct CryptoPacketBuf CryptoPacketBuf;
> >>> > +
> >>> > +typedef void (CryptoPacketSent) (CryptoClientState *, int);
> >> As previously, I'd expect naming of
> >>
> >>  QCryptoCryptodevPacket
> >>  QCryptoCryptodevPacketBuf
> >>  QCryptoCryptodevQueue
> >>
> >
> >Gonglei,
> >
> >you are copying a lot of code from network backends.
> >
> >I am not sure why you would need a queue for virtio-crypto rather than a
> >direct connection between frontend and backend (and the backend would be
> >QEMU crypto APIs, like Daniel suggested).
>
> What about backends implemented directly in HW? Bypass the middle man.
> Make crypto offload meaningful for small size blocks.
> 
As I said in other reply, I only provide interfaces, you can realize them according
to different backend cryptodevs.

Regards,
-Gonglei

> < Ola
> 
> >
> >Paolo
> >
> >---------------------------------------------------------------------
> >To unsubscribe, e-mail: virtio-dev-unsubscribe@lists.oasis-open.org
> >For additional commands, e-mail: virtio-dev-help@lists.oasis-open.org
> >
> 
> IMPORTANT NOTICE: The contents of this email and any attachments are
> confidential and may also be privileged. If you are not the intended recipient,
> please notify the sender immediately and do not disclose the contents to any
> other person, use it for any purpose, or store or copy the information in any
> medium. Thank you.
Ola Liljedahl Sept. 14, 2016, 8:24 a.m. UTC | #7
On 14/09/2016, 03:07, "Gonglei (Arei)" <arei.gonglei@huawei.com> wrote:

>Hi Ola,
>
>
>
>> -----Original Message-----
>> From: Ola Liljedahl [mailto:Ola.Liljedahl@arm.com]
>> Sent: Tuesday, September 13, 2016 7:53 PM
>> To: Paolo Bonzini; Daniel P. Berrange; Gonglei (Arei)
>> Cc: qemu-devel@nongnu.org; virtio-dev@lists.oasis-open.org; Huangpeng
>> (Peter); Luonengjun; mst@redhat.com; stefanha@redhat.com; Huangweidong
>> (C); mike.caraman@nxp.com; agraf@suse.de; xin.zeng@intel.com; Claudio
>> Fontana; nmorey@kalray.eu; vincent.jardin@6wind.com
>> Subject: Re: [virtio-dev] Re: [PATCH v2 02/15] crypto: introduce crypto
>>queue
>> handler
>>
>>
>>
>>
>>
>> On 13/09/2016, 12:58, "virtio-dev@lists.oasis-open.org on behalf of
>>Paolo
>> Bonzini" <virtio-dev@lists.oasis-open.org on behalf of
>> pbonzini@redhat.com> wrote:
>>
>> >
>> >
>> >On 13/09/2016 11:20, Daniel P. Berrange wrote:
>> >>> > +typedef struct CryptoPacket CryptoPacket;
>> >>> > +typedef struct CryptoQueue CryptoQueue;
>> >>> > +typedef struct CryptoPacketBuf CryptoPacketBuf;
>> >>> > +
>> >>> > +typedef void (CryptoPacketSent) (CryptoClientState *, int);
>> >> As previously, I'd expect naming of
>> >>
>> >>  QCryptoCryptodevPacket
>> >>  QCryptoCryptodevPacketBuf
>> >>  QCryptoCryptodevQueue
>> >>
>> >
>> >Gonglei,
>> >
>> >you are copying a lot of code from network backends.
>> >
>> >I am not sure why you would need a queue for virtio-crypto rather than
>>a
>> >direct connection between frontend and backend (and the backend would
>>be
>> >QEMU crypto APIs, like Daniel suggested).
>>
>> What about backends implemented directly in HW? Bypass the middle man.
>> Make crypto offload meaningful for small size blocks.
>>
>As I said in other reply, I only provide interfaces, you can realize them
>according
>to different backend cryptodevs.
Interfaces imposes contraints on performance and implementation. A poor
interface could make certain implementations unnecessarily difficult.
Since these virtio-* interfaces will live for a long time, we should
ensure that they do not impose unnecessary constraints. For functionality
like crypto and IPsec, I can see the benefit of implementing the backend
in HW (for the datapath).

>
>Regards,
>-Gonglei
>
>> < Ola
>>
>> >
>> >Paolo
>> >
>> >---------------------------------------------------------------------
>> >To unsubscribe, e-mail: virtio-dev-unsubscribe@lists.oasis-open.org
>> >For additional commands, e-mail: virtio-dev-help@lists.oasis-open.org
>> >
>>
>> IMPORTANT NOTICE: The contents of this email and any attachments are
>> confidential and may also be privileged. If you are not the intended
>>recipient,
>> please notify the sender immediately and do not disclose the contents
>>to any
>> other person, use it for any purpose, or store or copy the information
>>in any
>> medium. Thank you.
>

IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.
diff mbox

Patch

diff --git a/crypto/Makefile.objs b/crypto/Makefile.objs
index 2a63cb8..652b429 100644
--- a/crypto/Makefile.objs
+++ b/crypto/Makefile.objs
@@ -27,6 +27,7 @@  crypto-obj-y += block.o
 crypto-obj-y += block-qcow.o
 crypto-obj-y += block-luks.o
 crypto-obj-y += crypto.o
+crypto-obj-y += crypto-queue.o
 
 # Let the userspace emulators avoid linking gnutls/etc
 crypto-aes-obj-y = aes.o
diff --git a/crypto/crypto-queue.c b/crypto/crypto-queue.c
new file mode 100644
index 0000000..3e91be9
--- /dev/null
+++ b/crypto/crypto-queue.c
@@ -0,0 +1,206 @@ 
+/*
+ * Queue management for crypto device (based on net/qeueu.c)
+ *
+ * Copyright (c) 2003-2008 Fabrice Bellard
+ * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD.
+ *
+ * Authors:
+ *    Gonglei <arei.gonglei@huawei.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include "crypto/crypto-queue.h"
+#include "crypto/crypto.h"
+#include "qemu/queue.h"
+
+
+/* The delivery handler may only return zero if it will call
+ * qemu_crypto_queue_flush() when it determines that it is once again able
+ * to deliver packets. It must also call qemu_crypto_queue_purge() in its
+ * cleanup path.
+ *
+ * If a sent callback is provided to send(), the caller must handle a
+ * zero return from the delivery handler by not sending any more packets
+ * until we have invoked the callback. Only in that case will we queue
+ * the packet.
+ *
+ * If a sent callback isn't provided, we just drop the packet to avoid
+ * unbounded queueing.
+ */
+
+struct CryptoPacket {
+    QTAILQ_ENTRY(CryptoPacket) entry;
+    CryptoClientState *sender;
+    unsigned flags; /* algorithms' type etc. */
+    CryptoPacketSent *sent_cb; /* callback after packet sent */
+    void *opaque; /* header struct pointer of operation */
+    uint8_t data[0];
+};
+
+struct CryptoQueue {
+    void *opaque;
+    uint32_t nq_maxlen;
+    uint32_t nq_count;
+    CryptoQueueDeliverFunc *deliver;
+
+    QTAILQ_HEAD(packets, CryptoPacket) packets;
+
+    unsigned delivering:1;
+};
+
+CryptoQueue *
+qemu_new_crypto_queue(CryptoQueueDeliverFunc *deliver, void *opaque)
+{
+    CryptoQueue *queue;
+
+    queue = g_new0(CryptoQueue, 1);
+
+    queue->opaque = opaque;
+    queue->nq_maxlen = 10000;
+    queue->nq_count = 0;
+    queue->deliver = deliver;
+
+    QTAILQ_INIT(&queue->packets);
+
+    queue->delivering = 0;
+
+    return queue;
+}
+
+void qemu_del_crypto_queue(CryptoQueue *queue)
+{
+    CryptoPacket *packet, *next;
+
+    QTAILQ_FOREACH_SAFE(packet, &queue->packets, entry, next) {
+        QTAILQ_REMOVE(&queue->packets, packet, entry);
+        g_free(packet->opaque);
+        g_free(packet);
+    }
+
+    g_free(queue);
+}
+
+void qemu_crypto_queue_cache(CryptoQueue *queue,
+                               unsigned flags,
+                               CryptoClientState *sender,
+                               void *opaque,
+                               CryptoPacketSent *sent_cb)
+{
+    CryptoPacket *packet;
+
+    if (queue->nq_count >= queue->nq_maxlen && !sent_cb) {
+        return; /* drop if queue full and no callback */
+    }
+
+    packet = g_malloc(sizeof(CryptoPacket));
+    packet->sender = sender;
+    packet->sent_cb = sent_cb;
+    packet->flags = flags,
+    packet->opaque = opaque;
+
+    queue->nq_count++;
+    QTAILQ_INSERT_TAIL(&queue->packets, packet, entry);
+}
+
+static ssize_t qemu_crypto_queue_deliver(CryptoQueue *queue,
+                                         unsigned flags,
+                                         CryptoClientState *sender,
+                                         void *opaque)
+{
+    ssize_t ret = -1;
+
+    queue->delivering = 1;
+    ret = queue->deliver(sender, flags, opaque, queue->opaque);
+    queue->delivering = 0;
+
+    return ret;
+}
+
+int qemu_crypto_queue_send(CryptoQueue *queue,
+                            unsigned flags,
+                            CryptoClientState *sender,
+                            void *opaque,
+                            CryptoPacketSent *sent_cb)
+{
+    int ret;
+
+    if (queue->delivering) {
+        qemu_crypto_queue_cache(queue, flags, sender,
+                                opaque, sent_cb);
+        return 0;
+    }
+
+    ret = qemu_crypto_queue_deliver(queue, flags, sender, opaque);
+    if (ret == 0) {
+        qemu_crypto_queue_cache(queue, flags, sender,
+                                opaque, sent_cb);
+        return 0;
+    }
+
+    qemu_crypto_queue_flush(queue);
+
+    return ret;
+}
+
+void qemu_crypto_queue_purge(CryptoQueue *queue, CryptoClientState *from)
+{
+    CryptoPacket *packet, *next;
+
+    QTAILQ_FOREACH_SAFE(packet, &queue->packets, entry, next) {
+        if (packet->sender == from) {
+            QTAILQ_REMOVE(&queue->packets, packet, entry);
+            queue->nq_count--;
+            if (packet->sent_cb) {
+                packet->sent_cb(packet->sender, 0);
+            }
+            g_free(packet->opaque);
+            g_free(packet);
+        }
+    }
+}
+
+bool qemu_crypto_queue_flush(CryptoQueue *queue)
+{
+    while (!QTAILQ_EMPTY(&queue->packets)) {
+        CryptoPacket *packet;
+        int ret;
+
+        packet = QTAILQ_FIRST(&queue->packets);
+        QTAILQ_REMOVE(&queue->packets, packet, entry);
+        queue->nq_count--;
+
+        ret = qemu_crypto_queue_deliver(queue, packet->flags,
+                                        packet->sender, packet->opaque);
+        if (ret == 0) {
+            queue->nq_count++;
+            QTAILQ_INSERT_HEAD(&queue->packets, packet, entry);
+            return false;
+        }
+
+        if (packet->sent_cb) {
+            packet->sent_cb(packet->sender, ret);
+        }
+
+        g_free(packet->opaque);
+        g_free(packet);
+    }
+    return true;
+}
diff --git a/crypto/crypto.c b/crypto/crypto.c
index fbc6497..a0e4a34 100644
--- a/crypto/crypto.c
+++ b/crypto/crypto.c
@@ -151,6 +151,8 @@  static void crypto_client_setup(CryptoClientState *cc,
     }
     QTAILQ_INSERT_TAIL(&crypto_clients, cc, next);
     cc->destructor = destructor;
+    cc->incoming_queue =
+                qemu_new_crypto_queue(qemu_deliver_crypto_packet, cc);
 }
 
 CryptoClientState *new_crypto_client(CryptoClientInfo *info,
@@ -169,3 +171,29 @@  CryptoClientState *new_crypto_client(CryptoClientInfo *info,
 
     return cc;
 }
+
+int qemu_deliver_crypto_packet(CryptoClientState *sender,
+                              unsigned flags,
+                              void *header_opqaue,
+                              void *opaque)
+{
+    return 0;
+}
+
+int qemu_send_crypto_packet_async(CryptoClientState *sender,
+                                unsigned flags,
+                                void *opaque,
+                                CryptoPacketSent *sent_cb)
+{
+    CryptoQueue *queue;
+
+    if (!sender->ready) {
+        /* we assume that all packets are sent */
+        return 1;
+    }
+
+    queue = sender->peer->incoming_queue;
+
+    return qemu_crypto_queue_send(queue, flags, sender,
+                                  opaque, sent_cb);
+}
diff --git a/include/crypto/crypto-queue.h b/include/crypto/crypto-queue.h
new file mode 100644
index 0000000..6fba64d
--- /dev/null
+++ b/include/crypto/crypto-queue.h
@@ -0,0 +1,69 @@ 
+/*
+ * Copyright (c) 2003-2008 Fabrice Bellard
+ * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD.
+ *
+ * Authors:
+ *    Gonglei <arei.gonglei@huawei.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef QEMU_CRYPTO_QUEUE_H
+#define QEMU_CRYPTO_QUEUE_H
+
+#include "qemu-common.h"
+
+typedef struct CryptoPacket CryptoPacket;
+typedef struct CryptoQueue CryptoQueue;
+typedef struct CryptoPacketBuf CryptoPacketBuf;
+
+typedef void (CryptoPacketSent) (CryptoClientState *, int);
+
+
+/* Returns:
+ *   >0 - success
+ *    0 - queue packet for future redelivery
+ *   <0 - failure (discard packet)
+ */
+typedef int (CryptoQueueDeliverFunc)(CryptoClientState *sender,
+                                     unsigned flags,
+                                     void *header_opaque,
+                                     void *opaque);
+
+CryptoQueue *
+qemu_new_crypto_queue(CryptoQueueDeliverFunc *deliver, void *opaque);
+
+void qemu_crypto_queue_cache(CryptoQueue *queue,
+                               unsigned flags,
+                               CryptoClientState *sender,
+                               void *opaque,
+                               CryptoPacketSent *sent_cb);
+
+void qemu_del_crypto_queue(CryptoQueue *queue);
+
+int qemu_crypto_queue_send(CryptoQueue *queue,
+                                unsigned flags,
+                                CryptoClientState *sender,
+                                void *opaque,
+                                CryptoPacketSent *sent_cb);
+
+void qemu_crypto_queue_purge(CryptoQueue *queue, CryptoClientState *from);
+bool qemu_crypto_queue_flush(CryptoQueue *queue);
+
+#endif /* QEMU_CRYPTO_QUEUE_H */
diff --git a/include/crypto/crypto.h b/include/crypto/crypto.h
index f93f6f9..46b3b9e 100644
--- a/include/crypto/crypto.h
+++ b/include/crypto/crypto.h
@@ -29,6 +29,8 @@ 
 
 #include "qemu/queue.h"
 #include "qapi-types.h"
+#include "crypto/crypto-queue.h"
+
 
 typedef void (CryptoPoll)(CryptoClientState *, bool);
 typedef void (CryptoCleanup) (CryptoClientState *);
@@ -52,6 +54,8 @@  struct CryptoClientState {
     char *model;
     char *name;
     char info_str[256];
+    CryptoQueue *incoming_queue;
+    unsigned int queue_index;
     CryptoClientDestructor *destructor;
 };
 
@@ -62,5 +66,13 @@  CryptoClientState *new_crypto_client(CryptoClientInfo *info,
                                     CryptoClientState *peer,
                                     const char *model,
                                     const char *name);
+int qemu_deliver_crypto_packet(CryptoClientState *sender,
+                              unsigned flags,
+                              void *header_opqaue,
+                              void *opaque);
+int qemu_send_crypto_packet_async(CryptoClientState *sender,
+                                unsigned flags,
+                                void *opaque,
+                                CryptoPacketSent *sent_cb);
 
 #endif /* QCRYPTO_CRYPTO_H__ */