Next up in our hackathon series from p2k19 is one from Stefan Sperling (), who writes:

naddy@

krw@

At the university I was greeted by landry@ and pirofti@ with stories about packet loss. It is delightful to visit friends in remote places and finally get first-hand experience of their otherwise unreproducible wifi problems.

The Intel firmware was complaining about missing beacons from its access point, which was not surprising since there were well over 50 different wifi networks visible in the hackroom using available channels in an entirely uncoordinated manner. Simply raising our tolerance of missed beacon events prevented iwm(4) from reconnecting over and over, resolving the packet loss issue for the most part. Evidence gathered later suggests that simply waiting for students to leave the building and suspending classes for the week would have fixed the issue as well.

ajacoutot@ and mpi@ made various suggestions to improve tog(1), an ncurses-based Git repository browser shipped with Game of Trees. Their first suggestion was to make diffs more pleasant to read by showing them in color. There wasn't even any argument about the default color scheme.

Everyone agreed that mpi@ 's color scheme

The second suggestion, "Make it faster", is harder to resolve. Blaming deep file history going back to 1995 currently very slow. mpi@ helped me with getting meaningful data from the profiler and we determined two problems.

The first problem was that got-read-pack spent too much time decompressing data. Deltas in the pack file were already cached on a per-object basis to prevent repeated disk acess and decompression when the same object is requested multiple times.

But deltas can be shared between different objects, and the existing caching was ineffective for traversal access patterns which read a lot of objects just once, such as traversal of tree objects during a blame operation.

Adding a global LRU cache for deltas to got-read-pack addressed this issue, speeding up the operation of blaming a file's history by almost 50%, from about 60 seconds to just a bit over 30 seconds on my machine.

But 30 seconds is still too slow. Profiler data also highlighted a large number of memcpy(3) and free(3) calls. Game of Trees makes use of opaque data types to hide the implementation internals of one subsystem from other subsystems. This coding style makes extending and maintaining the code base easier, but also encourages a lot of dynamic memory allocation and copying of data between different regions of memory.

For example, as tree objects are traversed, tree objects and each of their entries get individually allocated and freed. This causes a relatively large amount of free(3) calls, with the upside of added memory protection from OpenBSD's malloc(3) and free(3) implementation, but with the downside of a relatively large proportion of execution time spent on providing such protection.

I am now working on a patch which allocates tree objects and their entries in a single area of memory. This speeds up the aforementioned blame test further by about 5 seconds. However, I don't plan on going down this road very far because the code is becoming a bit harder to follow as a result and memory protection is weakened.

Avoiding unnecessary memcpy(3) calls has implications on safety and also provides performance benefits. I have already removed unnecessary memcpy(3) calls from parsing of tree objects. Instead of decompressing to one buffer, creating a parsed representation of this data in another buffer, and copying that data into a buffer which gets copied into a pipe, the initial memory buffer can be used for all these steps until the data needs to be copied into the pipe. This same optimization could still be applied to other types of objects (commits, tags, and blobs).

Back to iwm(4), I committed my patches to upgrade 8260 and 8265 devices to firmware API revision 34, which is the lowest API level that allows 9260 devices to work. Unfortunately, I had accidentally packed a 7260 card instead of a 9260, and didn't have the right adapter to make use of the 9560 devices which kmos@ had generously brought for me. I did pack a 3168 card though, which was long known for having trouble loading firmware. I picked relevant fixes from Linux and FreeBSD, and 3168 devices are now supported.

I could further investigate another problem exposed by the University's wifi setup. Professor pirofti@ asked me and mpi@ to provide guest lectures for students of the University's operating systems class. I presented a re-run of my BSDCan 2019 presentation "Building an accessible OpenBSD laptop".

While mpi@ was giving his presentation I noticed that my laptop no longer connected to any wifi network. 'ifconfig iwm0 debug' output showed that it kept trying to connect to our hackroom wifi network, which was just about out of reach.

The hackroom access point appeared in scan results but did not reliably respond to authentication and association request frames. I patched the access point selection heuristic such that access points which fail to respond to these frames get a worse score during future selection decisions.

With this patch I could connect, and it was committed after some testing later that day which involved walking up and down the hallway staring at my laptop trying not to bump into people.

Because jcs@ and others brought an old discussion up again, the default behaviour of connecting to unknown open wifi networks was changed.

By default the interface will now keep scanning forever and only connect to known network. Connect to arbitrary unencrypted networks must now be explicitly enabled with ifconfig join "". This also means that OpenBSD machines no longer send unwanted auth and assoc requests to arbitrary networks while scanning.

This behaviour change required updating the ifconfig man page. While at the documentation of 'join' and 'scan' commands was rewritten for clarify, and sthen@ volunteered to clarify documentation about WPA configuration across all wifi driver man pages.

During firmware update testing nayden@ tripped across a crash which could be triggered if no matching iwm firmware was installed. The fix for this was released as an errata for OpenBSD 6.6 and 6.5.

Overall this hackathon was surprisingly productive for me, even though I never got around to working on 9260 hardware support. I very much enjoyed my stay in Bucharest, and Paul and the University were excellent hosts! We even got to spend some time off at a thermal bath. Good coffee with fresh Romanian Merdenea pastry is now my favourite hackathon breakfast.

During the weekend after the hackathon I could finally finish 9260 device support. This is now available in -current. There could still be minor glitches but we should be able to fix them in time for OpenBSD 6.7.