Re: [lng-odp] odp timer unit test case question
On Wed, May 20, 2015 at 05:28:24PM +0200, Ola Liljedahl wrote: On 20 May 2015 at 16:16, Jerin Jacob jerin.ja...@caviumnetworks.com wrote: On Wed, May 20, 2015 at 12:42:29PM +0200, Ola Liljedahl wrote: On 20 May 2015 at 06:56, Jerin Jacob jerin.ja...@caviumnetworks.com wrote: On Wed, May 20, 2015 at 12:25:12AM +0200, Ola Liljedahl wrote: On 19 May 2015 at 15:34, Jacob, Jerin jerin.ja...@caviumnetworks.com wrote: Ola, Is there any specific reason for following check in timer validation test ? pa diff --git a/test/validation/odp_timer.c b/test/validation/odp_timer.c index 554b353..724026e 100644 --- a/test/validation/odp_timer.c +++ b/test/validation/odp_timer.c @@ -260,7 +260,7 @@ static void handle_tmo(odp_event_t ev, bool stale, uint64_t prev_tick) if (ttp != NULL) { /* Internal error */ - CU_ASSERT_FATAL(ttp-ev == ODP_EVENT_INVALID); +--CU_ASSERT_FATAL(ttp-ev == ODP_EVENT_INVALID); ttp-ev = ev; } } AFAIU, I should be CU_ASSERT_FATAL(ttp-ev != ODP_EVENT_INVALID) as tt[i].ev = odp_timeout_to_event(odp_timeout_alloc(tbp)) specified while preparing all timers. Yes the timers are still inactive and the timeout event is stored in the 'ev' member. handle_timeout() is called for received timeouts (timer has expired). In that case, the corresponding 'ev' member should not contain any timeout event. Am I missing something in the timer specification ? Or the timer specification is missing something? odp_timer_set_abs(tt[i].tim, tck, tt[i].ev); (line 309) is supposed to grab the timeout event (on success) and clear the variable (write ODP_TIMEOUT_INVALID), that's why the timeout is passed by reference (tt[i].ev). Possibly this is not specified clearly enough in timer.h: * @param[in,out] tmo_ev Reference to an event variable that points to * timeout event or NULL to reuse the existing timeout event. Any existing * timeout event that is replaced by a successful set operation will be * returned here. The new timeout event is read from *tmo_ev. The old timeout event (if timer was active) or ODP_TIMEOUT_INVALID (if timer was inactive) is stored in *tmo_ev. I hope this is at least clear in the reference implementation. We are on same page, except the last notes IMO, linux generic timer implementation details leaked into creating the test case. Well I don't agree and I hope I can convince you. AFAIU, *tmo_ev should have the event that used for _arming_ the timer so that application can do some look up after receiving event through queue or something similar.. What is the point of providing ODP_TIMEOUT_INVALID to application back, What the use of it for the application. It is possible to set an already active timer (which then is already associated with a timeout). If the user specifies a new timeout, the old timeout must be returned to the user (because all alloc and free of timeouts is the responsibility of the user). So any old timeout (for an already active timer) is return in *tmo_ev. But it is possible that the timer has already expired (and the timeout been delivered) or wasn't active to start with. We want the application to be able to differ between these two scenarios and we achieve this by updating *tmo_ev accordingly. When the timer_set call return, if *tmo_ev != ODP_EVENT_INVALID, an timeout has been returned and the application needs to do something with it. If *tno_ev == ODP_EVENT_INVALID, no timeout was returned. Just to understand the usecase, What application is gonna do with returned *tmp_ev if timer is active and it returned the associated timeout ? Either the application specified a new timeout in the timer_set call and it is that timeout which will be delivered upon timer expiration. If a timeout is returned (the old timeout for an already active timer), the application should free it or re-use it. it can't free as it will be cause double free when it comes back in app mainloop(it will have odp_timeout_free() there). If a timeout is returned in *tmo_ev then it is not the same timeout. Old vs. new. and application can't use the returned associated timeout for long time what if it event is delivered and free'ed it in the main loop. Typical main loop application processing will be check for event type, process it and free the resources Is this scheme is replacement for the API like odp_timer_active() to find the timer active or not ? I thought the reason for returning *tmo_ev in timer set operation is that, if application is lazy(ie don't want to manage) to create the timeout event then it can ask for the implementation with 'NULL' so that implementation can get a odp timer event from the implementation and if
Re: [lng-odp] [PATCH 4/4] ipc: example app
On 05/20/2015 18:24, Ciprian Barbu wrote: On Fri, May 8, 2015 at 12:57 PM, Maxim Uvarov maxim.uva...@linaro.org wrote: Simple example app creates one packet i/o to external interface and one ipc pktio to other process. Then transfer packet from external interface to other process and back thought ipc queue. Signed-off-by: Maxim Uvarov maxim.uva...@linaro.org --- configure.ac| 1 + example/Makefile.am | 2 +- example/ipc/.gitignore | 1 + example/ipc/Makefile.am | 7 + example/ipc/odp_ipc.c | 427 5 files changed, 437 insertions(+), 1 deletion(-) create mode 100644 example/ipc/.gitignore create mode 100644 example/ipc/Makefile.am create mode 100644 example/ipc/odp_ipc.c diff --git a/configure.ac b/configure.ac index d20bad2..1ceb922 100644 --- a/configure.ac +++ b/configure.ac @@ -274,6 +274,7 @@ AC_CONFIG_FILES([Makefile example/Makefile example/classifier/Makefile example/generator/Makefile +example/ipc/Makefile example/ipsec/Makefile example/packet/Makefile example/timer/Makefile diff --git a/example/Makefile.am b/example/Makefile.am index 353f397..506963f 100644 --- a/example/Makefile.am +++ b/example/Makefile.am @@ -1 +1 @@ -SUBDIRS = classifier generator ipsec packet timer +SUBDIRS = classifier generator ipc ipsec packet timer diff --git a/example/ipc/.gitignore b/example/ipc/.gitignore new file mode 100644 index 000..963d99d --- /dev/null +++ b/example/ipc/.gitignore @@ -0,0 +1 @@ +odp_ipc diff --git a/example/ipc/Makefile.am b/example/ipc/Makefile.am new file mode 100644 index 000..3da9549 --- /dev/null +++ b/example/ipc/Makefile.am @@ -0,0 +1,7 @@ +include $(top_srcdir)/example/Makefile.inc + +bin_PROGRAMS = odp_ipc +odp_ipc_LDFLAGS = $(AM_LDFLAGS) -static +odp_ipc_CFLAGS = $(AM_CFLAGS) -I${top_srcdir}/example + +dist_odp_ipc_SOURCES = odp_ipc.c diff --git a/example/ipc/odp_ipc.c b/example/ipc/odp_ipc.c new file mode 100644 index 000..0ed5442 --- /dev/null +++ b/example/ipc/odp_ipc.c @@ -0,0 +1,427 @@ +/* Copyright (c) 2015, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @file + * + * @example odp_ipc.c ODP IPC test application. + */ + +#include stdlib.h +#include string.h +#include getopt.h +#include unistd.h + +#include example_debug.h + +#include odp.h +#include odp/helper/linux.h + +/** @def SHM_PKT_POOL_SIZE + * @brief Size of the shared memory block + */ +#define SHM_PKT_POOL_SIZE (512*2048) + +/** @def SHM_PKT_POOL_BUF_SIZE + * @brief Buffer size of the packet pool buffer + */ +#define SHM_PKT_POOL_BUF_SIZE 1856 + +/** @def MAX_PKT_BURST + * @brief Maximum number of packet bursts + */ +#define MAX_PKT_BURST 16 + +/** Get rid of path in filename - only for unix-type paths using '/' */ +#define NO_PATH(file_name) (strrchr((file_name), '/') ? \ + strrchr((file_name), '/') + 1 : (file_name)) + +/** Application argument */ +static char *pktio_name; + +/* helper funcs */ +static void parse_args(int argc, char *argv[]); +static void print_info(char *progname); +static void usage(char *progname); + +/** + * Create a pktio handle. + * + * @param dev Name of device to open + * @param pool Pool to associate with device for packet RX/TX + * + * @return The handle of the created pktio object. + * @retval ODP_PKTIO_INVALID if the create fails. + */ +static odp_pktio_t create_pktio(const char *dev, odp_pool_t pool) +{ + odp_pktio_t pktio; + odp_pktio_t ipc_pktio; + + /* Open a packet IO instance */ + pktio = odp_pktio_open(dev, pool); + if (pktio == ODP_PKTIO_INVALID) + EXAMPLE_ABORT(Error: pktio create failed for %s\n, dev); + + printf(pid: %d, create IPC pktio\n, getpid()); + ipc_pktio = odp_pktio_open(ipc_pktio, pool); I had some troubles starting the example, it was like the second process started but the main process would die for some reason. I tried to debug it with gdb but then it started working. It was around this line I think, I could see the message Wait for second process set mdata_offset... Did you see any strange behavior on your side, especially after a fresh boot? hm, did not see that but I will check. + if (ipc_pktio == ODP_PKTIO_INVALID) + EXAMPLE_ABORT(Error: ipc pktio create failed.\n); + + return pktio; +} + +/** + * Packet IO loopback worker thread using bursts from/to IO resources + * + * @param arg thread arguments of type 'thread_args_t *' + */ +static void *pktio_run_loop(odp_pool_t pool) +{ + int thr; + odp_pktio_t pktio; + int pkts; + odp_packet_t pkt_tbl[MAX_PKT_BURST]; + odp_pktio_t ipc_pktio; + thr = odp_thread_id(); + + pktio = odp_pktio_lookup(pktio_name); + if (pktio == ODP_PKTIO_INVALID) { +
Re: [lng-odp] [PATCH 1/2 v1] examples: ipsec: tunnel mode support
The changes look good to me. -Original Message- From: Maxim Uvarov [mailto:maxim.uva...@linaro.org] Sent: Thursday, May 21, 2015 12:47 PM To: lng-odp@lists.linaro.org; Steve Kordus (skordus) Subject: Re: [lng-odp] [PATCH 1/2 v1] examples: ipsec: tunnel mode support CC Steve, it he is not in mailing list. Maxim. On 05/19/2015 11:38, alexandru.badici...@linaro.org wrote: From: Alexandru Badicioiu alexandru.badici...@linaro.org v1 - added comment for tunnel DB entry use Tunnel mode is enabled from the command line using -t argument with the following format: SrcIP:DstIP:TunnelSrcIP:TunnelDstIP. SrcIP - cleartext packet source IP DstIP - cleartext packet destination IP TunnelSrcIP - tunnel source IP TunnelDstIP - tunnel destination IP The outbound packets matching SrcIP:DstIP will be encapsulated in a TunnelSrcIP:TunnelDstIP IPSec tunnel (AH/ESP/AH+ESP) if a matching outbound SA is determined (as for transport mode). For inbound packets each entry in the IPSec cache is matched for the cleartext addresses, as in the transport mode (SrcIP:DstIP) and then for the tunnel addresses (TunnelSrcIP:TunnelDstIP) in case cleartext addresses didn't match. After authentication and decryption tunneled packets are verified against the tunnel entry (packets came in from the expected tunnel). Signed-off-by: Alexandru Badicioiu alexandru.badici...@linaro.org --- example/ipsec/odp_ipsec.c| 105 +++--- example/ipsec/odp_ipsec_cache.c | 31 +- example/ipsec/odp_ipsec_cache.h |6 ++ example/ipsec/odp_ipsec_sa_db.c | 133 +- example/ipsec/odp_ipsec_sa_db.h | 57 example/ipsec/odp_ipsec_stream.c | 101 6 files changed, 403 insertions(+), 30 deletions(-) diff --git a/example/ipsec/odp_ipsec.c b/example/ipsec/odp_ipsec.c index 82ed0cb..3931fef 100644 --- a/example/ipsec/odp_ipsec.c +++ b/example/ipsec/odp_ipsec.c @@ -135,13 +135,20 @@ typedef struct { uint8_t ip_ttl; /** Saved IP TTL value */ int hdr_len;/** Length of IPsec headers */ int trl_len;/** Length of IPsec trailers */ + uint16_t tun_hdr_offset; /** Offset of tunnel header from + buffer start */ uint16_t ah_offset; /** Offset of AH header from buffer start */ uint16_t esp_offset; /** Offset of ESP header from buffer start */ + /* Input only */ + uint32_t src_ip; /** SA source IP address */ + uint32_t dst_ip; /** SA dest IP address */ + /* Output only */ odp_crypto_op_params_t params; /** Parameters for crypto call */ uint32_t *ah_seq; /** AH sequence number location */ uint32_t *esp_seq; /** ESP sequence number location */ + uint16_t *tun_hdr_id; /** Tunnel header ID */ } ipsec_ctx_t; /** @@ -368,6 +375,7 @@ void ipsec_init_pre(void) /* Initialize our data bases */ init_sp_db(); init_sa_db(); + init_tun_db(); init_ipsec_cache(); } @@ -387,19 +395,27 @@ void ipsec_init_post(crypto_api_mode_e api_mode) for (entry = sp_db-list; NULL != entry; entry = entry-next) { sa_db_entry_t *cipher_sa = NULL; sa_db_entry_t *auth_sa = NULL; + tun_db_entry_t *tun; - if (entry-esp) + if (entry-esp) { cipher_sa = find_sa_db_entry(entry-src_subnet, entry-dst_subnet, 1); - if (entry-ah) + tun = find_tun_db_entry(cipher_sa-src_ip, + cipher_sa-dst_ip); + } + if (entry-ah) { auth_sa = find_sa_db_entry(entry-src_subnet, entry-dst_subnet, 0); + tun = find_tun_db_entry(auth_sa-src_ip, + auth_sa-dst_ip); + } if (cipher_sa || auth_sa) { if (create_ipsec_cache_entry(cipher_sa, auth_sa, + tun, api_mode, entry-input, completionq, @@ -672,6 +688,8 @@ pkt_disposition_e do_ipsec_in_classify(odp_packet_t pkt, ctx-ipsec.esp_offset = esp ? ((uint8_t *)esp) - buf : 0; ctx-ipsec.hdr_len = hdr_len; ctx-ipsec.trl_len = 0; + ctx-ipsec.src_ip = entry-src_ip; + ctx-ipsec.dst_ip = entry-dst_ip;
Re: [lng-odp] [RFC] Add ipc.h
On 21 May 2015 at 13:22, Alexandru Badicioiu alexandru.badici...@linaro.org wrote: Hi, would Netlink protocol (https://tools.ietf.org/html/rfc3549) fit the purpose of ODP IPC (within a single OS instance)? I interpret this as a question whether Netlink would be fit as an implementation of the ODP IPC (now called message bus because IPC is so contended and imbued with different meanings). It is perhaps possible. Netlink seems a bit focused on intra-kernel and kernel-to-user while the ODP IPC-MBUS is focused on user-to-user (application-to-application). I see a couple of primary requirements: - Support communication (message exchange) between user space processes. - Support arbitrary used-defined messages. - Ordered, reliable delivery of messages. From the little I can quickly read up on Netlink, the first two requirements do not seem supported. But perhaps someone with more intimate knowledge of Netlink can prove me wrong. Or maybe Netlink can be extended to support u2u and user-defined messages, the current specialization (e.g. specialized addressing, specialized message formats) seems contrary to the goals of providing generic mechanisms in the kernel that can be used for different things. My IPC/MBUS reference implementation for linux-generic builds upon POSIX message queues. One of my issues is that I want the message queue associated with a process to go away when the process goes away. The message queues are not independent entities. -- Ola Thanks, Alex On 21 May 2015 at 14:12, Ola Liljedahl ola.liljed...@linaro.org wrote: On 21 May 2015 at 11:50, Savolainen, Petri (Nokia - FI/Espoo) petri.savolai...@nokia.com wrote: -Original Message- From: lng-odp [mailto:lng-odp-boun...@lists.linaro.org] On Behalf Of ext Ola Liljedahl Sent: Tuesday, May 19, 2015 1:04 AM To: lng-odp@lists.linaro.org Subject: [lng-odp] [RFC] Add ipc.h As promised, here is my first attempt at a standalone API for IPC - inter process communication in a shared nothing architecture (message passing between processes which do not share memory). Currently all definitions are in the file ipc.h but it is possible to break out some message/event related definitions (everything from odp_ipc_sender) in a separate file message.h. This would mimic the packet_io.h/packet.h separation. The semantics of message passing is that sending a message to an endpoint will always look like it succeeds. The appearance of endpoints is explicitly notified through user-defined messages specified in the odp_ipc_resolve() call. Similarly, the disappearance (e.g. death or otherwise lost connection) is also explicitly notified through user-defined messages specified in the odp_ipc_monitor() call. The send call does not fail because the addressed endpoints has disappeared. Messages (from endpoint A to endpoint B) are delivered in order. If message N sent to an endpoint is delivered, then all messages N have also been delivered. Message delivery does not guarantee actual processing by the Ordered is OK requirement, but all messages N have also been delivered means in practice loss less delivery (== re-tries and retransmission windows, etc). Lossy vs loss less link should be an configuration option. I am just targeting internal communication which I expect to be reliable. There is not any physical link involved. If an implementation chooses to use some unreliable media, then it will need to take some counter measures. Any loss of message could be detected using sequence numbers (and timeouts) and handled by (temporary) disconnection (so that no more messages will be delivered should one go missing). I am OK with adding the lossless/lossy configuration to the API as long as lossless option is always implemented. Is this a configuration when creating the local IPC endpoint or when sending a message to another endpoint? Also what delivered means?' Message: - transmitted successfully over the link ? - is now under control of the remote node (post office) ? - delivered into application input queue ? Probably this one but I am not sure the exact definition matters, has been delivered or will eventually be delivered unless connection to the destination is lost. Maybe there is a better word than delivered? Made available into the destination (recipient) address space? - has been dequeued from application queue ? recipient. End-to-end acknowledgements (using messages) should be used if this guarantee is important to the user. IPC endpoints can be seen as interfaces (taps) to an internal reliable multidrop network where each endpoint has a unique address which is only valid for the lifetime of the endpoint. I.e. if an endpoint is destroyed and then recreated (with the same name), the new endpoint will have a new address (eventually endpoints addresses will have to be recycled but not for
Re: [lng-odp] [RFC] Add ipc.h
I was referring to the Netlink protocol in itself, as a model for ODP MBUS (or IPC). The interaction between the FEC and the CPC, in the Netlink context, defines a protocol. Netlink provides mechanisms for the CPC (residing in user space) and the FEC (residing in kernel space) to have their own protocol definition -- *kernel space and user space just mean different protection domains*. Therefore, a wire protocol is needed to communicate. The wire protocol is normally provided by some privileged service that is able to copy between multiple protection domains. We will refer to this service as the Netlink service. The Netlink service can also be encapsulated in a different transport layer, if the CPC executes on a different node than the FEC. The FEC and CPC, using Netlink mechanisms, may choose to define a reliable protocol between each other. By default, however, Netlink provides an unreliable communication. Note that the FEC and CPC can both live in the same memory protection domain and use the connect() system call to create a path to the peer and talk to each other. We will not discuss this mechanism further other than to say that it is available. Throughout this document, we will refer interchangeably to the FEC to mean kernel space and the CPC to mean user space. This denomination is not meant, however, to restrict the two components to these protection domains or to the same compute node. On 21 May 2015 at 15:55, Ola Liljedahl ola.liljed...@linaro.org wrote: On 21 May 2015 at 13:22, Alexandru Badicioiu alexandru.badici...@linaro.org wrote: Hi, would Netlink protocol (https://tools.ietf.org/html/rfc3549) fit the purpose of ODP IPC (within a single OS instance)? I interpret this as a question whether Netlink would be fit as an implementation of the ODP IPC (now called message bus because IPC is so contended and imbued with different meanings). It is perhaps possible. Netlink seems a bit focused on intra-kernel and kernel-to-user while the ODP IPC-MBUS is focused on user-to-user (application-to-application). I see a couple of primary requirements: - Support communication (message exchange) between user space processes. - Support arbitrary used-defined messages. - Ordered, reliable delivery of messages. From the little I can quickly read up on Netlink, the first two requirements do not seem supported. But perhaps someone with more intimate knowledge of Netlink can prove me wrong. Or maybe Netlink can be extended to support u2u and user-defined messages, the current specialization (e.g. specialized addressing, specialized message formats) seems contrary to the goals of providing generic mechanisms in the kernel that can be used for different things. My IPC/MBUS reference implementation for linux-generic builds upon POSIX message queues. One of my issues is that I want the message queue associated with a process to go away when the process goes away. The message queues are not independent entities. -- Ola Thanks, Alex On 21 May 2015 at 14:12, Ola Liljedahl ola.liljed...@linaro.org wrote: On 21 May 2015 at 11:50, Savolainen, Petri (Nokia - FI/Espoo) petri.savolai...@nokia.com wrote: -Original Message- From: lng-odp [mailto:lng-odp-boun...@lists.linaro.org] On Behalf Of ext Ola Liljedahl Sent: Tuesday, May 19, 2015 1:04 AM To: lng-odp@lists.linaro.org Subject: [lng-odp] [RFC] Add ipc.h As promised, here is my first attempt at a standalone API for IPC - inter process communication in a shared nothing architecture (message passing between processes which do not share memory). Currently all definitions are in the file ipc.h but it is possible to break out some message/event related definitions (everything from odp_ipc_sender) in a separate file message.h. This would mimic the packet_io.h/packet.h separation. The semantics of message passing is that sending a message to an endpoint will always look like it succeeds. The appearance of endpoints is explicitly notified through user-defined messages specified in the odp_ipc_resolve() call. Similarly, the disappearance (e.g. death or otherwise lost connection) is also explicitly notified through user-defined messages specified in the odp_ipc_monitor() call. The send call does not fail because the addressed endpoints has disappeared. Messages (from endpoint A to endpoint B) are delivered in order. If message N sent to an endpoint is delivered, then all messages N have also been delivered. Message delivery does not guarantee actual processing by the Ordered is OK requirement, but all messages N have also been delivered means in practice loss less delivery (== re-tries and retransmission windows, etc). Lossy vs loss less link should be an configuration option. I am just targeting
Re: [lng-odp] [RFC] Add ipc.h
On 21 May 2015 at 11:50, Savolainen, Petri (Nokia - FI/Espoo) petri.savolai...@nokia.com wrote: -Original Message- From: lng-odp [mailto:lng-odp-boun...@lists.linaro.org] On Behalf Of ext Ola Liljedahl Sent: Tuesday, May 19, 2015 1:04 AM To: lng-odp@lists.linaro.org Subject: [lng-odp] [RFC] Add ipc.h As promised, here is my first attempt at a standalone API for IPC - inter process communication in a shared nothing architecture (message passing between processes which do not share memory). Currently all definitions are in the file ipc.h but it is possible to break out some message/event related definitions (everything from odp_ipc_sender) in a separate file message.h. This would mimic the packet_io.h/packet.h separation. The semantics of message passing is that sending a message to an endpoint will always look like it succeeds. The appearance of endpoints is explicitly notified through user-defined messages specified in the odp_ipc_resolve() call. Similarly, the disappearance (e.g. death or otherwise lost connection) is also explicitly notified through user-defined messages specified in the odp_ipc_monitor() call. The send call does not fail because the addressed endpoints has disappeared. Messages (from endpoint A to endpoint B) are delivered in order. If message N sent to an endpoint is delivered, then all messages N have also been delivered. Message delivery does not guarantee actual processing by the Ordered is OK requirement, but all messages N have also been delivered means in practice loss less delivery (== re-tries and retransmission windows, etc). Lossy vs loss less link should be an configuration option. I am just targeting internal communication which I expect to be reliable. There is not any physical link involved. If an implementation chooses to use some unreliable media, then it will need to take some counter measures. Any loss of message could be detected using sequence numbers (and timeouts) and handled by (temporary) disconnection (so that no more messages will be delivered should one go missing). I am OK with adding the lossless/lossy configuration to the API as long as lossless option is always implemented. Is this a configuration when creating the local IPC endpoint or when sending a message to another endpoint? Also what delivered means?' Message: - transmitted successfully over the link ? - is now under control of the remote node (post office) ? - delivered into application input queue ? Probably this one but I am not sure the exact definition matters, has been delivered or will eventually be delivered unless connection to the destination is lost. Maybe there is a better word than delivered? Made available into the destination (recipient) address space? - has been dequeued from application queue ? recipient. End-to-end acknowledgements (using messages) should be used if this guarantee is important to the user. IPC endpoints can be seen as interfaces (taps) to an internal reliable multidrop network where each endpoint has a unique address which is only valid for the lifetime of the endpoint. I.e. if an endpoint is destroyed and then recreated (with the same name), the new endpoint will have a new address (eventually endpoints addresses will have to be recycled but not for a very long time). Endpoints names do not necessarily have to be unique. How widely these addresses are unique: inside one VM, multiple VMs under the same host, multiple devices on a LAN (VLAN), ... Currently, the scope of the name and address space is defined by the implementation. Perhaps we should define it? My current interest is within an OS instance (bare metal or virtualised). Between different OS instances, I expect something based on IP to be used (because you don't know where those different OS/VM instances will be deployed so you need topology-independent addressing). Based on other feedback, I have dropped the contented usage of IPC and now call it message bus (MBUS). MBUS endpoints can be seen as interfaces (taps) to an OS-internal reliable multidrop network... Signed-off-by: Ola Liljedahl ola.liljed...@linaro.org --- (This document/code contribution attached is provided under the terms of agreement LES-LTM-21309) +/** + * Create IPC endpoint + * + * @param name Name of local IPC endpoint + * @param pool Pool for incoming messages + * + * @return IPC handle on success + * @retval ODP_IPC_INVALID on failure and errno set + */ +odp_ipc_t odp_ipc_create(const char *name, odp_pool_t pool); This creates (implicitly) the local end point address. + +/** + * Set the default input queue for an IPC endpoint + * + * @param ipc IPC handle + * @param queue Queue handle + * + * @retval 0 on success + * @retval 0 on failure + */ +int odp_ipc_inq_setdef(odp_ipc_t ipc, odp_queue_t queue); Multiple input queues are likely needed for different priority messages. + +/** + * Resolve endpoint by name +
Re: [lng-odp] [RFC] Add ipc.h
Hi, would Netlink protocol (https://tools.ietf.org/html/rfc3549) fit the purpose of ODP IPC (within a single OS instance)? Thanks, Alex On 21 May 2015 at 14:12, Ola Liljedahl ola.liljed...@linaro.org wrote: On 21 May 2015 at 11:50, Savolainen, Petri (Nokia - FI/Espoo) petri.savolai...@nokia.com wrote: -Original Message- From: lng-odp [mailto:lng-odp-boun...@lists.linaro.org] On Behalf Of ext Ola Liljedahl Sent: Tuesday, May 19, 2015 1:04 AM To: lng-odp@lists.linaro.org Subject: [lng-odp] [RFC] Add ipc.h As promised, here is my first attempt at a standalone API for IPC - inter process communication in a shared nothing architecture (message passing between processes which do not share memory). Currently all definitions are in the file ipc.h but it is possible to break out some message/event related definitions (everything from odp_ipc_sender) in a separate file message.h. This would mimic the packet_io.h/packet.h separation. The semantics of message passing is that sending a message to an endpoint will always look like it succeeds. The appearance of endpoints is explicitly notified through user-defined messages specified in the odp_ipc_resolve() call. Similarly, the disappearance (e.g. death or otherwise lost connection) is also explicitly notified through user-defined messages specified in the odp_ipc_monitor() call. The send call does not fail because the addressed endpoints has disappeared. Messages (from endpoint A to endpoint B) are delivered in order. If message N sent to an endpoint is delivered, then all messages N have also been delivered. Message delivery does not guarantee actual processing by the Ordered is OK requirement, but all messages N have also been delivered means in practice loss less delivery (== re-tries and retransmission windows, etc). Lossy vs loss less link should be an configuration option. I am just targeting internal communication which I expect to be reliable. There is not any physical link involved. If an implementation chooses to use some unreliable media, then it will need to take some counter measures. Any loss of message could be detected using sequence numbers (and timeouts) and handled by (temporary) disconnection (so that no more messages will be delivered should one go missing). I am OK with adding the lossless/lossy configuration to the API as long as lossless option is always implemented. Is this a configuration when creating the local IPC endpoint or when sending a message to another endpoint? Also what delivered means?' Message: - transmitted successfully over the link ? - is now under control of the remote node (post office) ? - delivered into application input queue ? Probably this one but I am not sure the exact definition matters, has been delivered or will eventually be delivered unless connection to the destination is lost. Maybe there is a better word than delivered? Made available into the destination (recipient) address space? - has been dequeued from application queue ? recipient. End-to-end acknowledgements (using messages) should be used if this guarantee is important to the user. IPC endpoints can be seen as interfaces (taps) to an internal reliable multidrop network where each endpoint has a unique address which is only valid for the lifetime of the endpoint. I.e. if an endpoint is destroyed and then recreated (with the same name), the new endpoint will have a new address (eventually endpoints addresses will have to be recycled but not for a very long time). Endpoints names do not necessarily have to be unique. How widely these addresses are unique: inside one VM, multiple VMs under the same host, multiple devices on a LAN (VLAN), ... Currently, the scope of the name and address space is defined by the implementation. Perhaps we should define it? My current interest is within an OS instance (bare metal or virtualised). Between different OS instances, I expect something based on IP to be used (because you don't know where those different OS/VM instances will be deployed so you need topology-independent addressing). Based on other feedback, I have dropped the contented usage of IPC and now call it message bus (MBUS). MBUS endpoints can be seen as interfaces (taps) to an OS-internal reliable multidrop network... Signed-off-by: Ola Liljedahl ola.liljed...@linaro.org --- (This document/code contribution attached is provided under the terms of agreement LES-LTM-21309) +/** + * Create IPC endpoint + * + * @param name Name of local IPC endpoint + * @param pool Pool for incoming messages + * + * @return IPC handle on success + * @retval ODP_IPC_INVALID on failure and errno set + */ +odp_ipc_t odp_ipc_create(const char *name, odp_pool_t pool); This creates (implicitly) the local end point address. + +/** + * Set the default input queue
Re: [lng-odp] [RFC] Add ipc.h
-Original Message- From: lng-odp [mailto:lng-odp-boun...@lists.linaro.org] On Behalf Of ext Ola Liljedahl Sent: Tuesday, May 19, 2015 1:04 AM To: lng-odp@lists.linaro.org Subject: [lng-odp] [RFC] Add ipc.h As promised, here is my first attempt at a standalone API for IPC - inter process communication in a shared nothing architecture (message passing between processes which do not share memory). Currently all definitions are in the file ipc.h but it is possible to break out some message/event related definitions (everything from odp_ipc_sender) in a separate file message.h. This would mimic the packet_io.h/packet.h separation. The semantics of message passing is that sending a message to an endpoint will always look like it succeeds. The appearance of endpoints is explicitly notified through user-defined messages specified in the odp_ipc_resolve() call. Similarly, the disappearance (e.g. death or otherwise lost connection) is also explicitly notified through user-defined messages specified in the odp_ipc_monitor() call. The send call does not fail because the addressed endpoints has disappeared. Messages (from endpoint A to endpoint B) are delivered in order. If message N sent to an endpoint is delivered, then all messages N have also been delivered. Message delivery does not guarantee actual processing by the Ordered is OK requirement, but all messages N have also been delivered means in practice loss less delivery (== re-tries and retransmission windows, etc). Lossy vs loss less link should be an configuration option. Also what delivered means? Message: - transmitted successfully over the link ? - is now under control of the remote node (post office) ? - delivered into application input queue ? - has been dequeued from application queue ? recipient. End-to-end acknowledgements (using messages) should be used if this guarantee is important to the user. IPC endpoints can be seen as interfaces (taps) to an internal reliable multidrop network where each endpoint has a unique address which is only valid for the lifetime of the endpoint. I.e. if an endpoint is destroyed and then recreated (with the same name), the new endpoint will have a new address (eventually endpoints addresses will have to be recycled but not for a very long time). Endpoints names do not necessarily have to be unique. How widely these addresses are unique: inside one VM, multiple VMs under the same host, multiple devices on a LAN (VLAN), ... Signed-off-by: Ola Liljedahl ola.liljed...@linaro.org --- (This document/code contribution attached is provided under the terms of agreement LES-LTM-21309) +/** + * Create IPC endpoint + * + * @param name Name of local IPC endpoint + * @param pool Pool for incoming messages + * + * @return IPC handle on success + * @retval ODP_IPC_INVALID on failure and errno set + */ +odp_ipc_t odp_ipc_create(const char *name, odp_pool_t pool); This creates (implicitly) the local end point address. + +/** + * Set the default input queue for an IPC endpoint + * + * @param ipc IPC handle + * @param queue Queue handle + * + * @retval 0 on success + * @retval 0 on failure + */ +int odp_ipc_inq_setdef(odp_ipc_t ipc, odp_queue_t queue); Multiple input queues are likely needed for different priority messages. + +/** + * Resolve endpoint by name + * + * Look up an existing or future endpoint by name. + * When the endpoint exists, return the specified message with the endpoint + * as the sender. + * + * @param ipc IPC handle + * @param name Name to resolve + * @param msg Message to return + */ +void odp_ipc_resolve(odp_ipc_t ipc, + const char *name, + odp_ipc_msg_t msg); How widely these names are visible? Inside one VM, multiple VMs under the same host, multiple devices on a LAN (VLAN), ... I think name service (or address resolution) are better handled in middleware layer. If ODP provides unique addresses and message passing mechanism, additional services can be built on top. + +/** + * Monitor endpoint + * + * Monitor an existing (potentially already dead) endpoint. + * When the endpoint is dead, return the specified message with the endpoint + * as the sender. + * + * Unrecognized or invalid endpoint addresses are treated as dead endpoints. + * + * @param ipc IPC handle + * @param addr Address of monitored endpoint + * @param msg Message to return + */ +void odp_ipc_monitor(odp_ipc_t ipc, + const uint8_t addr[ODP_IPC_ADDR_SIZE], + odp_ipc_msg_t msg); Again, I'd see node health monitoring and alarms as middleware services. + +/** + * Send message + * + * Send a message to an endpoint (which may already be dead). + * Message delivery is ordered and reliable. All (accepted) messages will be + * delivered up to the point of endpoint death or lost connection. + * Actual reception and processing is
Re: [lng-odp] odp timer unit test case question
On 21 May 2015 at 09:53, Jerin Jacob jerin.ja...@caviumnetworks.com wrote: On Wed, May 20, 2015 at 05:28:24PM +0200, Ola Liljedahl wrote: On 20 May 2015 at 16:16, Jerin Jacob jerin.ja...@caviumnetworks.com wrote: On Wed, May 20, 2015 at 12:42:29PM +0200, Ola Liljedahl wrote: On 20 May 2015 at 06:56, Jerin Jacob jerin.ja...@caviumnetworks.com wrote: On Wed, May 20, 2015 at 12:25:12AM +0200, Ola Liljedahl wrote: On 19 May 2015 at 15:34, Jacob, Jerin jerin.ja...@caviumnetworks.com wrote: Ola, Is there any specific reason for following check in timer validation test ? pa diff --git a/test/validation/odp_timer.c b/test/validation/odp_timer.c index 554b353..724026e 100644 --- a/test/validation/odp_timer.c +++ b/test/validation/odp_timer.c @@ -260,7 +260,7 @@ static void handle_tmo(odp_event_t ev, bool stale, uint64_t prev_tick) if (ttp != NULL) { /* Internal error */ - CU_ASSERT_FATAL(ttp-ev == ODP_EVENT_INVALID); +--CU_ASSERT_FATAL(ttp-ev == ODP_EVENT_INVALID); ttp-ev = ev; } } AFAIU, I should be CU_ASSERT_FATAL(ttp-ev != ODP_EVENT_INVALID) as tt[i].ev = odp_timeout_to_event(odp_timeout_alloc(tbp)) specified while preparing all timers. Yes the timers are still inactive and the timeout event is stored in the 'ev' member. handle_timeout() is called for received timeouts (timer has expired). In that case, the corresponding 'ev' member should not contain any timeout event. Am I missing something in the timer specification ? Or the timer specification is missing something? odp_timer_set_abs(tt[i].tim, tck, tt[i].ev); (line 309) is supposed to grab the timeout event (on success) and clear the variable (write ODP_TIMEOUT_INVALID), that's why the timeout is passed by reference (tt[i].ev). Possibly this is not specified clearly enough in timer.h: * @param[in,out] tmo_ev Reference to an event variable that points to * timeout event or NULL to reuse the existing timeout event. Any existing * timeout event that is replaced by a successful set operation will be * returned here. The new timeout event is read from *tmo_ev. The old timeout event (if timer was active) or ODP_TIMEOUT_INVALID (if timer was inactive) is stored in *tmo_ev. I hope this is at least clear in the reference implementation. We are on same page, except the last notes IMO, linux generic timer implementation details leaked into creating the test case. Well I don't agree and I hope I can convince you. AFAIU, *tmo_ev should have the event that used for _arming_ the timer so that application can do some look up after receiving event through queue or something similar.. What is the point of providing ODP_TIMEOUT_INVALID to application back, What the use of it for the application. It is possible to set an already active timer (which then is already associated with a timeout). If the user specifies a new timeout, the old timeout must be returned to the user (because all alloc and free of timeouts is the responsibility of the user). So any old timeout (for an already active timer) is return in *tmo_ev. But it is possible that the timer has already expired (and the timeout been delivered) or wasn't active to start with. We want the application to be able to differ between these two scenarios and we achieve this by updating *tmo_ev accordingly. When the timer_set call return, if *tmo_ev != ODP_EVENT_INVALID, an timeout has been returned and the application needs to do something with it. If *tno_ev == ODP_EVENT_INVALID, no timeout was returned. Just to understand the usecase, What application is gonna do with returned *tmp_ev if timer is active and it returned the associated timeout ? Either the application specified a new timeout in the timer_set call and it is that timeout which will be delivered upon timer expiration. If a timeout is returned (the old timeout for an already active timer), the application should free it or re-use it. it can't free as it will be cause double free when it comes back in app mainloop(it will have odp_timeout_free() there). If a timeout is returned in *tmo_ev then it is not the same timeout. Old vs. new. and application can't use the returned associated timeout for long time what if it event is delivered and free'ed it in the main loop. Typical main loop application processing will be check for event type, process it and free the resources Is this scheme is replacement for the API like odp_timer_active() to find the timer active or not ? I thought the reason for returning *tmo_ev in timer set operation is that, if application is lazy(ie don't want to manage) to create the timeout event then it can ask for the implementation with 'NULL' so
Re: [lng-odp] [RFC] Add ipc.h
On 21 May 2015 at 15:56, Alexandru Badicioiu alexandru.badici...@linaro.org wrote: I got the impression that ODP MBUS API would define a transport protocol/API between an ODP No the MBUS API is just an API for message passing (think of the OSE IPC API) and doesn't specify use cases or content. Just like the ODP packet API doesn't specify what the content in a packet means or the format of the content. application and a control plane application, like TCP is the transport protocol for HTTP applications (e.g Web). Netlink defines exactly that - transport protocol for configuration messages. Maxim asked about the messages - should applications define the message format and/or the message content? Wouldn't be an easier task for the application to define only the content and let ODP to define a format? How can you define a format when you don't know what the messages are used for and what data needs to be transferred? Why should the MBUS API or implementations care about the message format? It's just payload and none of their business. If you want to, you can specify formats for specific purposes, e.g. reuse Netlink formats for the functions that Netlink supports. Some ODP applications may use this, other not (because they use some other protocol or they implement some other functionality). Reliability could be an issue but Netlink spec says how applications can create reliable protocols: One could create a reliable protocol between an FEC and a CPC by using the combination of sequence numbers, ACKs, and retransmit timers. Both sequence numbers and ACKs are provided by Netlink; timers are provided by Linux. And you could do the same in ODP but I prefer not to, this adds a level of complexity to the application code I do not want. Perhaps the actual MBUS implementation has to do this but then hidden from the applications. Just like TCP reliability and ordering etc is hidden from the applications that just do read and write. One could create a heartbeat protocol between the FEC and CPC by using the ECHO flags and the NLMSG_NOOP message. On 21 May 2015 at 16:23, Ola Liljedahl ola.liljed...@linaro.org wrote: On 21 May 2015 at 15:05, Alexandru Badicioiu alexandru.badici...@linaro.org wrote: I was referring to the Netlink protocol in itself, as a model for ODP MBUS (or IPC). Isn't the Netlink protocol what the endpoints send between them? This is not specified by the ODP IPC/MBUS API, applications can define or re-use whatever protocol they like. The protocol definition is heavily dependent on what you actually use the IPC for and we shouldn't force ODP users to use some specific predefined protocol. Also the wire protocol is left undefined, this is up to the implementation to define and each platform can have its own definition. And netlink isn't even reliable. I know that that creates problems, e.g. impossible to get a clean and complete snapshot of e.g. the routing table. The interaction between the FEC and the CPC, in the Netlink context, defines a protocol. Netlink provides mechanisms for the CPC (residing in user space) and the FEC (residing in kernel space) to have their own protocol definition -- *kernel space and user space just mean different protection domains*. Therefore, a wire protocol is needed to communicate. The wire protocol is normally provided by some privileged service that is able to copy between multiple protection domains. We will refer to this service as the Netlink service. The Netlink service can also be encapsulated in a different transport layer, if the CPC executes on a different node than the FEC. The FEC and CPC, using Netlink mechanisms, may choose to define a reliable protocol between each other. By default, however, Netlink provides an unreliable communication. Note that the FEC and CPC can both live in the same memory protection domain and use the connect() system call to create a path to the peer and talk to each other. We will not discuss this mechanism further other than to say that it is available. Throughout this document, we will refer interchangeably to the FEC to mean kernel space and the CPC to mean user space. This denomination is not meant, however, to restrict the two components to these protection domains or to the same compute node. On 21 May 2015 at 15:55, Ola Liljedahl ola.liljed...@linaro.org wrote: On 21 May 2015 at 13:22, Alexandru Badicioiu alexandru.badici...@linaro.org wrote: Hi, would Netlink protocol (https://tools.ietf.org/html/rfc3549) fit the purpose of ODP IPC (within a single OS instance)? I interpret this as a question whether Netlink would be fit as an implementation of the ODP IPC (now called message bus because IPC is so contended and imbued with different meanings). It is perhaps possible. Netlink seems a bit focused on intra-kernel and kernel-to-user while the
Re: [lng-odp] [RFC] Add ipc.h
I got the impression that ODP MBUS API would define a transport protocol/API between an ODP application and a control plane application, like TCP is the transport protocol for HTTP applications (e.g Web). Netlink defines exactly that - transport protocol for configuration messages. Maxim asked about the messages - should applications define the message format and/or the message content? Wouldn't be an easier task for the application to define only the content and let ODP to define a format? Reliability could be an issue but Netlink spec says how applications can create reliable protocols: One could create a reliable protocol between an FEC and a CPC by using the combination of sequence numbers, ACKs, and retransmit timers. Both sequence numbers and ACKs are provided by Netlink; timers are provided by Linux. One could create a heartbeat protocol between the FEC and CPC by using the ECHO flags and the NLMSG_NOOP message. On 21 May 2015 at 16:23, Ola Liljedahl ola.liljed...@linaro.org wrote: On 21 May 2015 at 15:05, Alexandru Badicioiu alexandru.badici...@linaro.org wrote: I was referring to the Netlink protocol in itself, as a model for ODP MBUS (or IPC). Isn't the Netlink protocol what the endpoints send between them? This is not specified by the ODP IPC/MBUS API, applications can define or re-use whatever protocol they like. The protocol definition is heavily dependent on what you actually use the IPC for and we shouldn't force ODP users to use some specific predefined protocol. Also the wire protocol is left undefined, this is up to the implementation to define and each platform can have its own definition. And netlink isn't even reliable. I know that that creates problems, e.g. impossible to get a clean and complete snapshot of e.g. the routing table. The interaction between the FEC and the CPC, in the Netlink context, defines a protocol. Netlink provides mechanisms for the CPC (residing in user space) and the FEC (residing in kernel space) to have their own protocol definition -- *kernel space and user space just mean different protection domains*. Therefore, a wire protocol is needed to communicate. The wire protocol is normally provided by some privileged service that is able to copy between multiple protection domains. We will refer to this service as the Netlink service. The Netlink service can also be encapsulated in a different transport layer, if the CPC executes on a different node than the FEC. The FEC and CPC, using Netlink mechanisms, may choose to define a reliable protocol between each other. By default, however, Netlink provides an unreliable communication. Note that the FEC and CPC can both live in the same memory protection domain and use the connect() system call to create a path to the peer and talk to each other. We will not discuss this mechanism further other than to say that it is available. Throughout this document, we will refer interchangeably to the FEC to mean kernel space and the CPC to mean user space. This denomination is not meant, however, to restrict the two components to these protection domains or to the same compute node. On 21 May 2015 at 15:55, Ola Liljedahl ola.liljed...@linaro.org wrote: On 21 May 2015 at 13:22, Alexandru Badicioiu alexandru.badici...@linaro.org wrote: Hi, would Netlink protocol (https://tools.ietf.org/html/rfc3549) fit the purpose of ODP IPC (within a single OS instance)? I interpret this as a question whether Netlink would be fit as an implementation of the ODP IPC (now called message bus because IPC is so contended and imbued with different meanings). It is perhaps possible. Netlink seems a bit focused on intra-kernel and kernel-to-user while the ODP IPC-MBUS is focused on user-to-user (application-to-application). I see a couple of primary requirements: - Support communication (message exchange) between user space processes. - Support arbitrary used-defined messages. - Ordered, reliable delivery of messages. From the little I can quickly read up on Netlink, the first two requirements do not seem supported. But perhaps someone with more intimate knowledge of Netlink can prove me wrong. Or maybe Netlink can be extended to support u2u and user-defined messages, the current specialization (e.g. specialized addressing, specialized message formats) seems contrary to the goals of providing generic mechanisms in the kernel that can be used for different things. My IPC/MBUS reference implementation for linux-generic builds upon POSIX message queues. One of my issues is that I want the message queue associated with a process to go away when the process goes away. The message queues are not independent entities. -- Ola Thanks, Alex On 21 May 2015 at 14:12, Ola Liljedahl ola.liljed...@linaro.org wrote: On 21 May 2015 at 11:50, Savolainen, Petri
Re: [lng-odp] [RFC] Add ipc.h
On 21 May 2015 at 15:05, Alexandru Badicioiu alexandru.badici...@linaro.org wrote: I was referring to the Netlink protocol in itself, as a model for ODP MBUS (or IPC). Isn't the Netlink protocol what the endpoints send between them? This is not specified by the ODP IPC/MBUS API, applications can define or re-use whatever protocol they like. The protocol definition is heavily dependent on what you actually use the IPC for and we shouldn't force ODP users to use some specific predefined protocol. Also the wire protocol is left undefined, this is up to the implementation to define and each platform can have its own definition. And netlink isn't even reliable. I know that that creates problems, e.g. impossible to get a clean and complete snapshot of e.g. the routing table. The interaction between the FEC and the CPC, in the Netlink context, defines a protocol. Netlink provides mechanisms for the CPC (residing in user space) and the FEC (residing in kernel space) to have their own protocol definition -- *kernel space and user space just mean different protection domains*. Therefore, a wire protocol is needed to communicate. The wire protocol is normally provided by some privileged service that is able to copy between multiple protection domains. We will refer to this service as the Netlink service. The Netlink service can also be encapsulated in a different transport layer, if the CPC executes on a different node than the FEC. The FEC and CPC, using Netlink mechanisms, may choose to define a reliable protocol between each other. By default, however, Netlink provides an unreliable communication. Note that the FEC and CPC can both live in the same memory protection domain and use the connect() system call to create a path to the peer and talk to each other. We will not discuss this mechanism further other than to say that it is available. Throughout this document, we will refer interchangeably to the FEC to mean kernel space and the CPC to mean user space. This denomination is not meant, however, to restrict the two components to these protection domains or to the same compute node. On 21 May 2015 at 15:55, Ola Liljedahl ola.liljed...@linaro.org wrote: On 21 May 2015 at 13:22, Alexandru Badicioiu alexandru.badici...@linaro.org wrote: Hi, would Netlink protocol (https://tools.ietf.org/html/rfc3549) fit the purpose of ODP IPC (within a single OS instance)? I interpret this as a question whether Netlink would be fit as an implementation of the ODP IPC (now called message bus because IPC is so contended and imbued with different meanings). It is perhaps possible. Netlink seems a bit focused on intra-kernel and kernel-to-user while the ODP IPC-MBUS is focused on user-to-user (application-to-application). I see a couple of primary requirements: - Support communication (message exchange) between user space processes. - Support arbitrary used-defined messages. - Ordered, reliable delivery of messages. From the little I can quickly read up on Netlink, the first two requirements do not seem supported. But perhaps someone with more intimate knowledge of Netlink can prove me wrong. Or maybe Netlink can be extended to support u2u and user-defined messages, the current specialization (e.g. specialized addressing, specialized message formats) seems contrary to the goals of providing generic mechanisms in the kernel that can be used for different things. My IPC/MBUS reference implementation for linux-generic builds upon POSIX message queues. One of my issues is that I want the message queue associated with a process to go away when the process goes away. The message queues are not independent entities. -- Ola Thanks, Alex On 21 May 2015 at 14:12, Ola Liljedahl ola.liljed...@linaro.org wrote: On 21 May 2015 at 11:50, Savolainen, Petri (Nokia - FI/Espoo) petri.savolai...@nokia.com wrote: -Original Message- From: lng-odp [mailto:lng-odp-boun...@lists.linaro.org] On Behalf Of ext Ola Liljedahl Sent: Tuesday, May 19, 2015 1:04 AM To: lng-odp@lists.linaro.org Subject: [lng-odp] [RFC] Add ipc.h As promised, here is my first attempt at a standalone API for IPC - inter process communication in a shared nothing architecture (message passing between processes which do not share memory). Currently all definitions are in the file ipc.h but it is possible to break out some message/event related definitions (everything from odp_ipc_sender) in a separate file message.h. This would mimic the packet_io.h/packet.h separation. The semantics of message passing is that sending a message to an endpoint will always look like it succeeds. The appearance of endpoints is explicitly notified through user-defined messages specified in the odp_ipc_resolve() call. Similarly, the disappearance
[lng-odp] [PATCHv6 2/5] api ipc: update ring with shm proc argument
Signed-off-by: Maxim Uvarov maxim.uva...@linaro.org --- helper/include/odp/helper/ring.h | 2 ++ helper/ring.c| 9 - 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/helper/include/odp/helper/ring.h b/helper/include/odp/helper/ring.h index 65c32ad..5e640a7 100644 --- a/helper/include/odp/helper/ring.h +++ b/helper/include/odp/helper/ring.h @@ -158,6 +158,8 @@ typedef struct odph_ring { #define ODPH_RING_F_SP_ENQ 0x0001 /* The default enqueue is single-producer.*/ #define ODPH_RING_F_SC_DEQ 0x0002 /* The default dequeue is single-consumer.*/ +#define ODPH_RING_SHM_PROC 0x0004 /* If set - ring is visible from different + processes. Default is thread visible. */ #define ODPH_RING_QUOT_EXCEED (1 31) /* Quota exceed for burst ops */ #define ODPH_RING_SZ_MASK (unsigned)(0x0fff) /* Ring size mask */ diff --git a/helper/ring.c b/helper/ring.c index 721c1fc..4224518 100644 --- a/helper/ring.c +++ b/helper/ring.c @@ -158,8 +158,14 @@ odph_ring_create(const char *name, unsigned count, unsigned flags) char ring_name[ODPH_RING_NAMESIZE]; odph_ring_t *r; size_t ring_size; + uint32_t shm_flag; odp_shm_t shm; + if (flags ODPH_RING_SHM_PROC) + shm_flag = ODP_SHM_PROC; + else + shm_flag = 0; + /* count must be a power of 2 */ if (!ODP_VAL_IS_POWER_2(count) || (count ODPH_RING_SZ_MASK)) { ODP_ERR(Requested size is invalid, must be power of 2, and do not exceed the size limit %u\n, @@ -172,7 +178,8 @@ odph_ring_create(const char *name, unsigned count, unsigned flags) odp_rwlock_write_lock(qlock); /* reserve a memory zone for this ring.*/ - shm = odp_shm_reserve(ring_name, ring_size, ODP_CACHE_LINE_SIZE, 0); + shm = odp_shm_reserve(ring_name, ring_size, ODP_CACHE_LINE_SIZE, + shm_flag); r = odp_shm_addr(shm); -- 1.9.1 ___ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp
[lng-odp] [PATCHv6 1/5] linux-generic: zero params for pool create
Adding more params to pool create breaks original work. Make sure that not set params are zero. Signed-off-by: Maxim Uvarov maxim.uva...@linaro.org --- platform/linux-generic/odp_schedule.c | 1 + test/validation/odp_queue.c | 1 + 2 files changed, 2 insertions(+) diff --git a/platform/linux-generic/odp_schedule.c b/platform/linux-generic/odp_schedule.c index 7fe42d7..a63f97a 100644 --- a/platform/linux-generic/odp_schedule.c +++ b/platform/linux-generic/odp_schedule.c @@ -123,6 +123,7 @@ int odp_schedule_init_global(void) memset(sched, 0, sizeof(sched_t)); + memset(params, 0, sizeof(params)); params.buf.size = sizeof(sched_cmd_t); params.buf.align = 0; params.buf.num = NUM_SCHED_CMD; diff --git a/test/validation/odp_queue.c b/test/validation/odp_queue.c index 5123939..e541658 100644 --- a/test/validation/odp_queue.c +++ b/test/validation/odp_queue.c @@ -18,6 +18,7 @@ static int init_queue_suite(void) { odp_pool_param_t params; + memset(params, 0, sizeof(params)); params.buf.size = 0; params.buf.align = ODP_CACHE_LINE_SIZE; params.buf.num = 1024 * 10; -- 1.9.1 ___ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [PATCH 1/2 v1] examples: ipsec: tunnel mode support
CC Steve, it he is not in mailing list. Maxim. On 05/19/2015 11:38, alexandru.badici...@linaro.org wrote: From: Alexandru Badicioiu alexandru.badici...@linaro.org v1 - added comment for tunnel DB entry use Tunnel mode is enabled from the command line using -t argument with the following format: SrcIP:DstIP:TunnelSrcIP:TunnelDstIP. SrcIP - cleartext packet source IP DstIP - cleartext packet destination IP TunnelSrcIP - tunnel source IP TunnelDstIP - tunnel destination IP The outbound packets matching SrcIP:DstIP will be encapsulated in a TunnelSrcIP:TunnelDstIP IPSec tunnel (AH/ESP/AH+ESP) if a matching outbound SA is determined (as for transport mode). For inbound packets each entry in the IPSec cache is matched for the cleartext addresses, as in the transport mode (SrcIP:DstIP) and then for the tunnel addresses (TunnelSrcIP:TunnelDstIP) in case cleartext addresses didn't match. After authentication and decryption tunneled packets are verified against the tunnel entry (packets came in from the expected tunnel). Signed-off-by: Alexandru Badicioiu alexandru.badici...@linaro.org --- example/ipsec/odp_ipsec.c| 105 +++--- example/ipsec/odp_ipsec_cache.c | 31 +- example/ipsec/odp_ipsec_cache.h |6 ++ example/ipsec/odp_ipsec_sa_db.c | 133 +- example/ipsec/odp_ipsec_sa_db.h | 57 example/ipsec/odp_ipsec_stream.c | 101 6 files changed, 403 insertions(+), 30 deletions(-) diff --git a/example/ipsec/odp_ipsec.c b/example/ipsec/odp_ipsec.c index 82ed0cb..3931fef 100644 --- a/example/ipsec/odp_ipsec.c +++ b/example/ipsec/odp_ipsec.c @@ -135,13 +135,20 @@ typedef struct { uint8_t ip_ttl; /** Saved IP TTL value */ int hdr_len;/** Length of IPsec headers */ int trl_len;/** Length of IPsec trailers */ + uint16_t tun_hdr_offset; /** Offset of tunnel header from + buffer start */ uint16_t ah_offset; /** Offset of AH header from buffer start */ uint16_t esp_offset; /** Offset of ESP header from buffer start */ + /* Input only */ + uint32_t src_ip; /** SA source IP address */ + uint32_t dst_ip; /** SA dest IP address */ + /* Output only */ odp_crypto_op_params_t params; /** Parameters for crypto call */ uint32_t *ah_seq; /** AH sequence number location */ uint32_t *esp_seq; /** ESP sequence number location */ + uint16_t *tun_hdr_id; /** Tunnel header ID */ } ipsec_ctx_t; /** @@ -368,6 +375,7 @@ void ipsec_init_pre(void) /* Initialize our data bases */ init_sp_db(); init_sa_db(); + init_tun_db(); init_ipsec_cache(); } @@ -387,19 +395,27 @@ void ipsec_init_post(crypto_api_mode_e api_mode) for (entry = sp_db-list; NULL != entry; entry = entry-next) { sa_db_entry_t *cipher_sa = NULL; sa_db_entry_t *auth_sa = NULL; + tun_db_entry_t *tun; - if (entry-esp) + if (entry-esp) { cipher_sa = find_sa_db_entry(entry-src_subnet, entry-dst_subnet, 1); - if (entry-ah) + tun = find_tun_db_entry(cipher_sa-src_ip, + cipher_sa-dst_ip); + } + if (entry-ah) { auth_sa = find_sa_db_entry(entry-src_subnet, entry-dst_subnet, 0); + tun = find_tun_db_entry(auth_sa-src_ip, + auth_sa-dst_ip); + } if (cipher_sa || auth_sa) { if (create_ipsec_cache_entry(cipher_sa, auth_sa, +tun, api_mode, entry-input, completionq, @@ -672,6 +688,8 @@ pkt_disposition_e do_ipsec_in_classify(odp_packet_t pkt, ctx-ipsec.esp_offset = esp ? ((uint8_t *)esp) - buf : 0; ctx-ipsec.hdr_len = hdr_len; ctx-ipsec.trl_len = 0; + ctx-ipsec.src_ip = entry-src_ip; + ctx-ipsec.dst_ip = entry-dst_ip; /*If authenticating, zero the mutable fields build the request */ if (ah) { @@ -752,6 +770,23 @@ pkt_disposition_e do_ipsec_in_finish(odp_packet_t pkt, trl_len += esp_t-pad_len + sizeof(*esp_t); } + /* We have a tunneled IPv4 packet */ + if (ip-proto == ODPH_IPV4)
Re: [lng-odp] [PATCH] platform: Makefile.inc: use `` instead of != for compatibility with older versions of Make
Merged, Maxim. On 05/19/2015 11:31, Nicolas Morey-Chaisemartin wrote: Suggested-by: Maxim Uvarov maxim.uva...@linaro.org Signed-off-by: Nicolas Morey-Chaisemartin nmo...@kalray.eu --- platform/Makefile.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/Makefile.inc b/platform/Makefile.inc index f232daa..f64e37c 100644 --- a/platform/Makefile.inc +++ b/platform/Makefile.inc @@ -12,6 +12,6 @@ lib_LTLIBRARIES = $(LIB)/libodp.la AM_LDFLAGS += -version-number '$(ODP_LIBSO_VERSION)' -GIT_DESC !=$(top_srcdir)/scripts/git_hash.sh +GIT_DESC = `$(top_srcdir)/scripts/git_hash.sh` AM_CFLAGS += -DGIT_HASH=$(GIT_DESC) AM_CFLAGS += -DPLATFORM=${with_platform} ___ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp ___ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp
Re: [lng-odp] [PATCH] validation: pktio: do not destroy pool
Hello Stuart, please review that patch. Thank you, Maxim. On 05/20/2015 12:31, Maxim Uvarov wrote: Some platforms like DPDK and Cavium bare metal can not dynamically destroy and create pool with the same name. Keep pool destroy only in test suite termination to make all other pktio tests passed. Signed-off-by: Maxim Uvarov maxim.uva...@linaro.org --- test/validation/odp_pktio.c | 66 ++--- 1 file changed, 39 insertions(+), 27 deletions(-) diff --git a/test/validation/odp_pktio.c b/test/validation/odp_pktio.c index d4bf7bf..7c1a666 100644 --- a/test/validation/odp_pktio.c +++ b/test/validation/odp_pktio.c @@ -56,6 +56,8 @@ odp_pool_t default_pkt_pool = ODP_POOL_INVALID; /** sequence number of IP packets */ odp_atomic_u32_t ip_seq; +odp_pool_t pool[MAX_NUM_IFACES] = {ODP_POOL_INVALID, ODP_POOL_INVALID}; + static void pktio_pkt_set_macs(odp_packet_t pkt, pktio_info_t *src, pktio_info_t *dst) { @@ -219,29 +221,11 @@ static int default_pool_create(void) return 0; } -static odp_pktio_t create_pktio(const char *iface) +static odp_pktio_t create_pktio(const char *iface, int num) { - odp_pool_t pool; odp_pktio_t pktio; - char pool_name[ODP_POOL_NAME_LEN]; - odp_pool_param_t params; - memset(params, 0, sizeof(params)); - params.pkt.seg_len = PKT_BUF_SIZE; - params.pkt.len = PKT_BUF_SIZE; - params.pkt.num = PKT_BUF_NUM; - params.type= ODP_POOL_PACKET; - - snprintf(pool_name, sizeof(pool_name), pkt_pool_%s, iface); - - pool = odp_pool_lookup(pool_name); - if (pool != ODP_POOL_INVALID) - CU_ASSERT(odp_pool_destroy(pool) == 0); - - pool = odp_pool_create(pool_name, ODP_SHM_NULL, params); - CU_ASSERT(pool != ODP_POOL_INVALID); - - pktio = odp_pktio_open(iface, pool); + pktio = odp_pktio_open(iface, pool[num]); if (pktio == ODP_PKTIO_INVALID) pktio = odp_pktio_lookup(iface); CU_ASSERT(pktio != ODP_PKTIO_INVALID); @@ -431,7 +415,7 @@ static void pktio_test_txrx(odp_queue_type_t q_type, int num_pkts) io = pktios[i]; io-name = iface_name[i]; - io-id = create_pktio(iface_name[i]); + io-id = create_pktio(iface_name[i], i); if (io-id == ODP_PKTIO_INVALID) { CU_FAIL(failed to open iface); return; @@ -487,7 +471,7 @@ static void test_odp_pktio_mtu(void) { int ret; int mtu; - odp_pktio_t pktio = create_pktio(iface_name[0]); + odp_pktio_t pktio = create_pktio(iface_name[0], 0); mtu = odp_pktio_mtu(pktio); CU_ASSERT(mtu 0); @@ -503,7 +487,7 @@ static void test_odp_pktio_mtu(void) static void test_odp_pktio_promisc(void) { int ret; - odp_pktio_t pktio = create_pktio(iface_name[0]); + odp_pktio_t pktio = create_pktio(iface_name[0], 0); ret = odp_pktio_promisc_mode_set(pktio, 1); CU_ASSERT(0 == ret); @@ -530,7 +514,7 @@ static void test_odp_pktio_mac(void) unsigned char mac_addr[ODPH_ETHADDR_LEN]; int mac_len; int ret; - odp_pktio_t pktio = create_pktio(iface_name[0]); + odp_pktio_t pktio = create_pktio(iface_name[0], 0); printf(testing mac for %s\n, iface_name[0]); @@ -553,7 +537,7 @@ static void test_odp_pktio_mac(void) static void test_odp_pktio_inq_remdef(void) { - odp_pktio_t pktio = create_pktio(iface_name[0]); + odp_pktio_t pktio = create_pktio(iface_name[0], 0); odp_queue_t inq; odp_event_t ev; int i; @@ -582,7 +566,7 @@ static void test_odp_pktio_open(void) /* test the sequence open-close-open-close() */ for (i = 0; i 2; ++i) { - pktio = create_pktio(iface_name[0]); + pktio = create_pktio(iface_name[0], 0); CU_ASSERT(pktio != ODP_PKTIO_INVALID); CU_ASSERT(odp_pktio_close(pktio) == 0); } @@ -613,7 +597,7 @@ static void test_odp_pktio_inq(void) { odp_pktio_t pktio; - pktio = create_pktio(iface_name[0]); + pktio = create_pktio(iface_name[0], 0); CU_ASSERT(pktio != ODP_PKTIO_INVALID); CU_ASSERT(create_inq(pktio, ODP_QUEUE_TYPE_POLL) == 0); @@ -621,12 +605,35 @@ static void test_odp_pktio_inq(void) CU_ASSERT(odp_pktio_close(pktio) == 0); } +static int create_pool(const char *iface, int num) +{ + char pool_name[ODP_POOL_NAME_LEN]; + odp_pool_param_t params; + + memset(params, 0, sizeof(params)); + params.pkt.seg_len = PKT_BUF_SIZE; + params.pkt.len = PKT_BUF_SIZE; + params.pkt.num = PKT_BUF_NUM; + params.type= ODP_POOL_PACKET; + + snprintf(pool_name, sizeof(pool_name), pkt_pool_%s, iface); + + pool[num] = odp_pool_create(pool_name, ODP_SHM_NULL, params); + if