
iperf - issue #128
better error message for CPU affinity failure, add FreeBSD support
On OSX I get this:
iperf3: error - unable to set CPU affinity:
Maybe a better error message would "Setting CPU affinity not supported in OSX" ?
Comment #1
Posted on Dec 20, 2013 by Happy Kangaroo(No comment was entered for this change.)
Comment #2
Posted on Dec 22, 2013 by Happy HippoI guess this should do it . Don't have Mac :(
$ hg diff
diff -r 1536985dc854 src/iperf_error.c
--- a/src/iperf_error.c Fri Dec 20 15:05:21 2013 -0800
+++ b/src/iperf_error.c Sun Dec 22 20:21:38 2013 +0530
@@ -238,7 +238,11 @@
snprintf(errstr, len, "protocol does not exist");
break;
case IEAFFINITY:
+#if defined(APPLE) && defined(MACH)
+ snprintf(errstr, len, "Setting CPU affinity not supported in OSX");
+#else
snprintf(errstr, len, "unable to set CPU affinity");
+#endif
perr = 1;
break;
case IEDAEMON:
Comment #3
Posted on Jan 3, 2014 by Happy DogOne though occurred to me as I was looking at this...given that (at the moment) this feature is only supported on Linux, why do we even allow users to specify the -A option on platforms that don't support it?
(Just for completeness, I note that FreeBSD allows setting CPU affinity, but the API is completely different, see cpuset_getaffinity(2).)
Comment #4
Posted on Jan 4, 2014 by Swift GiraffeI agree, just eliminate the ability to use -A in OSX, and add an issue to add freeBSD support in the future is probably the way to go.
Comment #5
Posted on Jan 5, 2014 by Happy HippoI implemented in freebsd with ifdef linux and freebsd. Tested with freebsd 9.2 with a 4 cpu having 4 core each . Guess it's working .
./iperf3 -s -A 1
Server listening on 5201
./iperf3 -s -A 20 iperf3: error - unable to set CPU affinity: Resource deadlock avoided
- freebsd_affinity.patch 2.73KB
Comment #6
Posted on Jan 6, 2014 by Happy DogI looked at the patch in Comment 5. Looks mostly good (at least it's mostly along the lines of what I had in mind).
It's doing something that's a little different on FreeBSD than on Linux. On Linux, -A takes either a single integer or two integers separated by commas. Let's ignore the second case for now. The single integer appears to be a CPU number because it's used directly as the first argument to CPU_SET.
On FreeBSD, it takes the same parameters, but the single-integer parameter is used as a bitmask...almost like it's being used to recreate the CPU affinity mask. It seems to me that to make FreeBSD to behave the same as Linux we should replace the loop in the FreeBSD case with a single call to CPU_SET:
CPU_SET(affinity, &cpumask);
According to FreeBSD's cpuset(2) manpage, -1 can be used as the id_t argument to cpuset_* (with cpuset_which set to CPUSET_PID) to indicate "this process". So there's a (very small) optimization that can be made here to avoid the call to getpid() and just use -1 instead of the id variable.
We probably need some code in iperf_clearaffinity() to handle FreeBSD as well. I think this code would be extremely similar to the Linux case in that it'd pass a cpumask of all 1s to cpuset_setaffinity(2).
Thanks for making all of the -A support conditional. There's at least one comment that says "Linux only" or some such thing that should be expanded to include FreeBSD.
Comment #7
Posted on Jan 7, 2014 by Happy HippoI modified from getpid() to -1. And also got rid of some variables .
The issues came in iperf_clearaffinity I tried to do in the same way as linux. Binding a process to each CPU available let us unbind. It really did not worked out. Then Introduced a variable for freebsd 'cpumask' . The trick is to before binding store the current cpumask and while clearaffinity restore the same . This worked.
- freebsd_cpu_affinity.patch 6.47KB
Comment #8
Posted on Jan 13, 2014 by Happy DogCommitted a modified version of the patch from Comment 7 in 85f085ddd2cb...thanks!
Closing as fixed.
Status: Fixed
Labels:
Type-Defect
Priority-Medium
Milestone-3.0-Release