linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* stmmac ethernet in kernel 4.4: coalescing related pauses?
@ 2016-11-23 10:51 Pavel Machek
  2016-11-24  8:55 ` stmmac ethernet in kernel 4.9-rc6: coalescing related pauses Pavel Machek
  2016-11-28 13:07 ` stmmac ethernet in kernel 4.4: coalescing related pauses? Lino Sanfilippo
  0 siblings, 2 replies; 64+ messages in thread
From: Pavel Machek @ 2016-11-23 10:51 UTC (permalink / raw)
  To: peppe.cavallaro, netdev, kernel list


[-- Attachment #1.1: Type: text/plain, Size: 933 bytes --]

Hi!

I'm debugging strange delays during transmit in stmmac driver. They
seem to be present in 4.4 kernel (and older kernels, too). Workload is
burst of udp packets being sent, pause, burst of udp packets, ...

Test code is attached, I use these parameters for testing:

./udp-test raw 10.0.0.6 1234 1000 100 30

The delays seem to be related to coalescing:

drivers/net/ethernet/stmicro/stmmac/common.h
#define STMMAC_COAL_TX_TIMER    40000
#define STMMAC_MAX_COAL_TX_TICK 100000
#define STMMAC_TX_MAX_FRAMES    256

If I lower the parameters, delays are gone, but I get netdev watchdog
backtrace followed by broken driver.

Any ideas what is going on there?

[I'm currently trying to get newer kernels working on affected
hardware.]

Best regards,

									Pavel
-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

[-- Attachment #1.2: CMakeLists.txt --]
[-- Type: text/plain, Size: 589 bytes --]

cmake_minimum_required(VERSION 2.8.7)
project(streaming)

find_package(Boost REQUIRED COMPONENTS system)

set(SOURCES 
	udp-test.cpp)

add_executable(udp-test ${SOURCES})

if (BUILD_TESTS)
  enable_testing()
endif()

set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -std=c++11")

set_property(TARGET udp-test PROPERTY CXX_STANDARD 11)
target_link_libraries(udp-test boost_system pthread )

[-- Attachment #1.3: udp-test.cpp --]
[-- Type: text/x-c++src, Size: 6995 bytes --]

#include <boost/asio.hpp>
#include <boost/asio/steady_timer.hpp>
#include <iostream>


namespace asio = boost::asio;

class UdpSendTest
{
	public:
		UdpSendTest(asio::io_service& io_service, const std::string& dest_ip, int dest_port, int packet_size, int packet_count, int interval)
			: io_service_(io_service),
	   		timer_(io_service),
			udp_socket_(io_service),
			dest_ip_(std::move(dest_ip)),
			dest_port_(dest_port),
			packet_size_(packet_size),
			packet_count_(packet_count),
			period_(interval)
		{
		}

		void start()
		{
			timer_.expires_from_now(period_);
			timer_.async_wait(std::bind(&UdpSendTest::handleTimer, this, std::placeholders::_1));
			try
			{
				udp_socket_.connect(asio::ip::udp::endpoint(boost::asio::ip::address::from_string(dest_ip_), dest_port_));
			}
			catch(boost::system::system_error e)
			{
				std::cerr<< "Could not connect:"<<e.what()<<std::endl;
			}
		}
	private:
		static_assert(std::chrono::steady_clock::is_steady, "steady_clock does not use the monotonic system clock. Please use a toolchain with full support for std::chrono!");

		void sendPackets()
		{
			std::vector<unsigned char> buffer(packet_size_,0);
			
			for (int i=0; i<packet_count_; i++)
			{
				if (buffer.size() > 1)
				{
					buffer[0] = i / 255;
					buffer[1] = i % 255;
				}
				else
					buffer[0]=i%255;

				auto t0 = std::chrono::steady_clock::now();
				try
				{
					udp_socket_.send(asio::buffer(buffer));
				}
				catch(boost::system::system_error& error)
				{
					std::cerr<<"Could not send UDP packet, reason: "<<error.what()<<std::endl;
				}
				auto delta_t = std::chrono::steady_clock::now() - t0;
				auto delta_t_us = std::chrono::duration_cast<std::chrono::microseconds>(delta_t).count();
				if (delta_t_us > 10000)
				{
					std::cout<<"Sending UDP packet took >10ms: "<<delta_t_us<<"us"<<std::endl;
				}
				if (delta_t_us > period_.count() * 1000)
				{
					std::cout<<"This would lead to a lost frame!"<<std::endl;
				}
			}
		}

		void handleTimer(boost::system::error_code ec)
		{
			if (ec)
			{
				std::cerr<<"Timer interrupted, exiting!"<<std::endl;
				return;
			}

			sendPackets();
			timer_.expires_at(timer_.expires_at() + period_);
			timer_.async_wait(std::bind(&UdpSendTest::handleTimer, this, std::placeholders::_1));

		}

		asio::io_service& io_service_;
		asio::steady_timer timer_;

		asio::ip::udp::socket udp_socket_;

		std::string dest_ip_;
		int dest_port_;
		int packet_size_;
		int packet_count_;
		std::chrono::milliseconds period_;
};

class UdpSendTestLowlevel
{
	public:
		UdpSendTestLowlevel(asio::io_service& io_service, const std::string& dest_ip, int dest_port, int packet_size, int packet_count, int interval)
			: io_service_(io_service),
	   		timer_(io_service),
			dest_ip_(std::move(dest_ip)),
			dest_port_(dest_port),
			packet_size_(packet_size),
			packet_count_(packet_count),
			period_(interval)
		{
		}

		void start()
		{
			timer_.expires_from_now(period_);
			timer_.async_wait(std::bind(&UdpSendTestLowlevel::handleTimer, this, std::placeholders::_1));
			socket_fd_ = socket(AF_INET, SOCK_DGRAM, 0);
			if (socket_fd_ < 0)
				std::cerr<<"could not create socket: " <<strerror(errno)<<std::endl;

			auto h = gethostbyname(dest_ip_.c_str());
			if (h == nullptr)
				std::cerr<<"Could not find host: "<<dest_ip_<<std::endl;

			server_addr_.sin_family = h->h_addrtype;
			memcpy((char*)&server_addr_.sin_addr.s_addr, h->h_addr_list[0], h->h_length);
			server_addr_.sin_port = htons(dest_port_);

			client_addr_.sin_family = AF_INET;
			client_addr_.sin_addr.s_addr = htonl(INADDR_ANY);
			client_addr_.sin_port = htons(0);
			auto rc = bind(socket_fd_,reinterpret_cast<sockaddr*>(&client_addr_), sizeof(client_addr_));
			if (rc < 0)
				std::cerr<<"Could not open Port"<<std::endl;
		}
	private:
		static_assert(std::chrono::steady_clock::is_steady, "steady_clock does not use the monotonic system clock. Please use a toolchain with full support for std::chrono!");

		void sendPackets()
		{
			std::vector<unsigned char> buffer(packet_size_,0);
			
			for (int i=0; i<packet_count_; i++)
			{
				if (buffer.size() > 1)
				{
					buffer[0] = i / 255;
					buffer[1] = i % 255;
				}
				else
					buffer[0]=i%255;

				auto t0 = std::chrono::steady_clock::now();
				auto rc = sendto(socket_fd_, buffer.data(), buffer.size(), 0, (sockaddr* )&server_addr_, sizeof(server_addr_));
				if (rc<0)
					std::cerr<<"Could not send UDP packet"<<std::endl;
				auto delta_t = std::chrono::steady_clock::now() - t0;
				auto delta_t_us = std::chrono::duration_cast<std::chrono::microseconds>(delta_t).count();
				if (delta_t_us > 10000)
				{
					std::cout<<"Sending UDP packet took >10ms: "<<delta_t_us<<"us"<<std::endl;
				}
				if (delta_t_us > period_.count() * 1000)
				{
					std::cout<<"This would lead to a lost frame!"<<std::endl;
				}
			}
		}

		void handleTimer(boost::system::error_code ec)
		{
			if (ec)
			{
				std::cerr<<"Timer interrupted, exiting!"<<std::endl;
				return;
			}

			sendPackets();
			timer_.expires_at(timer_.expires_at() + period_);
			timer_.async_wait(std::bind(&UdpSendTestLowlevel::handleTimer, this, std::placeholders::_1));

		}

		asio::io_service& io_service_;
		asio::steady_timer timer_;

		std::string dest_ip_;
		int dest_port_;
		int packet_size_;
		int packet_count_;
		std::chrono::milliseconds period_;

		int socket_fd_;
		struct sockaddr_in client_addr_, server_addr_;
};
int main(int argc, char** argv)
{
	if (argc < 7)
	{
		std::cout<<"usage: "<<argv[0]<<" [boost|raw] dest_ip dest_port packet_size packet_count interval_ms"<<std::endl;
		return 1;
	}
	if (std::atoi(argv[4])<1)
	{
		std::cerr<<"Please select a packet size > 0 bytes!"<<std::endl;
		return 1;
	}
	asio::io_service io_service;
	
	std::string mode(argv[1]);

	int dest_port = std::atoi(argv[3]);
	int packet_size = std::atoi(argv[4]);
	int packet_count = std::atoi(argv[5]);
	int frame_interval = std::atoi(argv[6]);

	int bytes_per_sec = packet_size * packet_count *(1000.f/frame_interval);
	int bytes_per_sec_2 = (packet_size+12) * packet_count *(1000.f/frame_interval);
	std::cout<<"Sending "<<packet_count<<" packets ("<<packet_size<<"b each) at an interval of "<<frame_interval<<"ms, expected data rate:"<<bytes_per_sec <<"b/s ("<<bytes_per_sec_2<<"b/s incl udp overhead)"<<std::endl;
	if (bytes_per_sec_2 > 1000 * 1000 * 100)
		std::cerr<<"Warning: trying to transmit > 100Mb/s"<<std::endl;

	if (mode == "boost")
	{
	
		UdpSendTest u(io_service,
				argv[2],dest_port, packet_size, packet_count, frame_interval);
		u.start();
		io_service.run();
	}
	else
	{
		UdpSendTestLowlevel u(io_service,
				argv[2],dest_port, packet_size, packet_count, frame_interval);
		u.start();
		io_service.run();
	}

	return 0;
}

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 181 bytes --]

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

end of thread, other threads:[~2016-12-11 19:57 UTC | newest]

Thread overview: 64+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-11-23 10:51 stmmac ethernet in kernel 4.4: coalescing related pauses? Pavel Machek
2016-11-24  8:55 ` stmmac ethernet in kernel 4.9-rc6: coalescing related pauses Pavel Machek
2016-11-24 10:29   ` Pavel Machek
2016-11-24 10:36     ` Pavel Machek
2016-11-24 10:46       ` [PATCH] stmmac ethernet: unify locking Pavel Machek
2016-11-24 11:05         ` [PATCH] stmmac ethernet: remove cut & paste code Pavel Machek
2016-11-24 20:05           ` Joe Perches
2016-11-24 21:44             ` Pavel Machek
2016-11-24 22:27               ` Joe Perches
2016-11-28 11:50                 ` Pavel Machek
2016-11-28 14:24                   ` Joe Perches
2016-11-28 14:35                     ` Pavel Machek
2016-11-28 16:03                       ` Joe Perches
2016-11-24 16:04   ` stmmac ethernet in kernel 4.9-rc6: coalescing related pauses David Miller
2016-11-24 21:25     ` Pavel Machek
2016-12-02  8:24       ` Giuseppe CAVALLARO
2016-12-02  8:41         ` Giuseppe CAVALLARO
2016-12-02  8:45         ` Pavel Machek
2016-12-02  9:43           ` Giuseppe CAVALLARO
2016-12-02 12:32             ` Pavel Machek
2016-12-02 13:51               ` Giuseppe CAVALLARO
2016-12-02 14:26                 ` Alexandre Torgue
2016-12-02 15:19                   ` Giuseppe CAVALLARO
2016-12-05 12:14                     ` Pavel Machek
2016-12-05 12:01                 ` Pavel Machek
2016-12-05 10:15             ` Pavel Machek
2016-12-05 11:40               ` Lino Sanfilippo
2016-12-05 22:02                 ` Pavel Machek
2016-12-05 22:37                   ` Lino Sanfilippo
2016-12-05 22:40                     ` Pavel Machek
2016-12-05 22:54                       ` Lino Sanfilippo
2016-12-05 23:11                         ` Lino Sanfilippo
2016-12-02 14:05           ` Aw: " Lino Sanfilippo
2016-12-07 12:31             ` [RFC] " Pavel Machek
2016-12-07 13:18               ` Lino Sanfilippo
2016-12-05 11:56         ` Pavel Machek
2016-11-28 11:55     ` [PATCH] stmmac: fix comments, make debug output consistent Pavel Machek
2016-11-30  0:53       ` David Miller
2016-11-28 12:13     ` stmmac ethernet in kernel 4.9-rc6: coalescing related pauses Pavel Machek
2016-11-28 12:17     ` [PATCH] stmmac: reduce code duplication getting basic descriptors Pavel Machek
2016-11-28 15:25       ` kbuild test robot
2016-12-02 14:09       ` Alexandre Torgue
2016-11-30 11:44     ` [PATCH] stmmac: simplify flag assignment Pavel Machek
2016-12-01 20:23       ` David Miller
2016-12-01 22:48         ` stmmac: turn coalescing / NAPI off in stmmac Pavel Machek
2016-12-02  8:39           ` Giuseppe CAVALLARO
2016-12-02 10:42             ` Pavel Machek
2016-12-02 15:31               ` Giuseppe CAVALLARO
2016-12-05 11:45                 ` Pavel Machek
2016-12-02  8:27       ` [PATCH] stmmac: simplify flag assignment Giuseppe CAVALLARO
2016-12-01 10:32     ` [PATCH] stmmac: cleanup documenation, make it match reality Pavel Machek
2016-12-03 20:07       ` David Miller
2016-12-05 12:27     ` [PATCH] stmmac: disable tx coalescing Pavel Machek
2016-12-11 19:07       ` Pavel Machek
2016-12-11 19:31         ` David Miller
2016-12-11 19:57           ` Pavel Machek
2016-11-28 13:07 ` stmmac ethernet in kernel 4.4: coalescing related pauses? Lino Sanfilippo
2016-11-28 14:54   ` David Miller
2016-11-28 15:31     ` Eric Dumazet
2016-11-28 15:57       ` Lino Sanfilippo
2016-11-28 16:30         ` David Miller
2016-11-28 17:01           ` Lino Sanfilippo
2016-11-30 10:28       ` Pavel Machek
2016-11-28 15:33     ` Lino Sanfilippo

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).