From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wi0-f173.google.com (mail-wi0-f173.google.com [209.85.212.173]) by dpdk.org (Postfix) with ESMTP id 0865CB619 for ; Mon, 16 Feb 2015 18:35:10 +0100 (CET) Received: by mail-wi0-f173.google.com with SMTP id bs8so27569712wib.0 for ; Mon, 16 Feb 2015 09:35:09 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:organization :user-agent:in-reply-to:references:mime-version :content-transfer-encoding:content-type; bh=6Aw81uroSWNFnxYvbT5jdPCetNqf89BOFDoocrkws2Q=; b=PykOgrDYe4D55PSDABJDiNfjWMnqHbDDyIwLT/ePZj1m6VWFYjW6/fbDkF7VHAHKE6 FOTzCluddA9YErtp9WDsq6YDTrvkpO9yKlyE5FlGaGxhN8Zss9+SUrWNZGjgvTSHRLAS /0gyx49zfF7YGqMdEycZ93aVZjvKXUE2wQ4fyZxgDSoX6/qvk6Ho1udEgrxA+G7sx/XG uV6CsvEzdc7Ld+rODyKCOakayYZAy52whPQ2gK0Y0pkJqjiMNVIOYUW71NjyRLwkl04B giCfQUnZ5LUOIbKg+LqozVubWd6C8FZPf7MpJcJKpfGIMleJGds7jJeZbUsodiVGJtYr 10TA== X-Gm-Message-State: ALoCoQnvMX4O6UzBJAG/5ul8pI/ZyYGlXZ1z9oP5PWONJwbD0/91Fl/EmpuTvm8B8ypsFbqhiKyq X-Received: by 10.194.57.199 with SMTP id k7mr53495794wjq.1.1424108109749; Mon, 16 Feb 2015 09:35:09 -0800 (PST) Received: from xps13.localnet (6wind.net2.nerim.net. [213.41.180.237]) by mx.google.com with ESMTPSA id cf12sm23784544wjb.10.2015.02.16.09.35.08 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 16 Feb 2015 09:35:08 -0800 (PST) From: Thomas Monjalon To: Bruce Richardson Date: Mon, 16 Feb 2015 18:34:37 +0100 Message-ID: <4549532.PTBUOYF3p0@xps13> Organization: 6WIND User-Agent: KMail/4.14.4 (Linux/3.18.4-1-ARCH; KDE/4.14.4; x86_64; ; ) In-Reply-To: <20150216151622.GA1888@bricha3-MOBL3> References: <1419266844-4848-1-git-send-email-bruce.richardson@intel.com> <54E1FFC4.1060605@6wind.com> <20150216151622.GA1888@bricha3-MOBL3> MIME-Version: 1.0 Content-Transfer-Encoding: 7Bit Content-Type: text/plain; charset="us-ascii" Cc: dev@dpdk.org Subject: Re: [dpdk-dev] [PATCH v2 3/4] examples: example showing use of callbacks. X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 16 Feb 2015 17:35:10 -0000 2015-02-16 15:16, Bruce Richardson: > On Mon, Feb 16, 2015 at 03:33:40PM +0100, Olivier MATZ wrote: > > Hi John, > > > > On 02/13/2015 04:39 PM, John McNamara wrote: > > > From: Richardson, Bruce > > > > > > Example showing how callbacks can be used to insert a timestamp > > > into each packet on RX. On TX the timestamp is used to calculate > > > the packet latency through the app, in cycles. > > > > > > Signed-off-by: Bruce Richardson > > > > > > I'm looking at the example and I don't understand what is the advantage > > of having callbacks in ethdev layer, knowing that the application can > > do the same job by a standard function call. > > > > What is the advantage of having callbacks compared to: > > > > > > for (port = 0; port < nb_ports; port++) { > > struct rte_mbuf *bufs[BURST_SIZE]; > > const uint16_t nb_rx = rte_eth_rx_burst(port, 0, > > bufs, BURST_SIZE); > > if (unlikely(nb_rx == 0)) > > continue; > > add_timestamp(bufs, nb_rx); > > > > const uint16_t nb_tx = rte_eth_tx_burst(port ^ 1, 0, > > bufs, nb_rx); > > calc_latency(bufs, nb_tx); > > > > if (unlikely(nb_tx < nb_rx)) { > > uint16_t buf; > > for (buf = nb_tx; buf < nb_rx; buf++) > > rte_pktmbuf_free(bufs[buf]); > > } > > } > > > > > > To me, doing like the code above has several advantages: > > > > - code is more readable: the callback is explicitly invoked, so there is > > no risk to forget it > > - code is faster: the functions calls can be inlined by the compiler > > - easier to handle error cases in the callback function as the error > > code is accessible to the application > > - there is no need to add code in ethdev api to do this > > - if the application does not want to use callbacks (I suppose most > > applications), it won't have any performance impact > > > > Regards, > > Olivier > > In this specific instance, given that the application does little else, there > is no real advantage to using the callbacks - it's just to have a simple example > of how they can be used. > > Where callbacks are really designed to be useful, is for extending or augmenting > hardware capabilities. Taking the example of sequence numbers - to use the most > trivial example - an application could be written to take advantage of sequence > numbers written to packets by the hardware which received them. However, if such > an application was to be used with a NIC which does not provide sequence numbering > capability, for example, anything using ixgbe driver, the application writer has > two choices - either modify his application code to check each packet for > a sequence number in the data path, and add it there post-rx, or alternatively, > to check the NIC capabilities at initialization time, and add a callback there > at initialization, if the hardware does not support it. In the latter case, > the main packet processing body of the application can be written as though > hardware always has sequence numbering capability, safe in the knowledge that > any hardware not supporting it will be back-filled by a software fallback at > initialization-time. > > By the same token, we could also look to extend hardware capabilities. For > different filtering or hashing capabilities, there can be limits in hardware > which are far less than what we need to use in software. Again, callbacks will > allow the data path to be written in a way that is oblivious to the underlying > hardware limits, because software will transparently fill in the gaps. > > Hope this makes the use case clear. After thinking more about these callbacks, I realize these callbacks won't help, as Olivier said. With callback, 1/ application checks device capability 2/ application provides hardware emulation as DPDK callback 3/ application forgets previous steps 4/ application calls DPDK Rx 5/ DPDK calls callback (without calling optimization) Without callback, 1/ application checks device capability 2/ application provides hardware emulation as internal function 3/ application set an internal device-flag to enable this function 4/ application calls DPDK Rx 5/ application calls the hardware emulation if flag is set So the only difference is to keep persistent the device information in the application instead of storing it as a function pointer in the DPDK struct. You can also be faster with this approach: at initialization time, you can check that your NIC supports the feature and use a specific mainloop that adds or not the sequence number without any runtime test. A callback could be justified for asynchronous events, or when doing specific processing in the middle of the driver, for instance when freeing a mbuf. But in this case it's exactly similar to do the processing in the application after Rx (or before Tx).