https://www.freebsd.org/cgi/man.cgi?query=queue&apropos=0&se...
https://github.com/freebsd/freebsd-src/blob/main/sys/sys/que...
https://www.freebsd.org/cgi/man.cgi?query=queue&apropos=0&se...
https://github.com/freebsd/freebsd-src/blob/main/sys/sys/que...
In general the BSD implementations are more type-safe (just plain type-safe, actually), and IMO easier to use and much simpler to understand.
`sys/queue.h` has it's pointers to the next element rather than the next list_node, while `ccan` and `linux` have pointers to the next list_node, which then are adjusted if needed to obtain the containing element.
In practice, this means that `sys/queue.h` is entirely macros, while linux & ccan's lists can use normal functions for most operations (with primarily obtaining the element pointer being handled by macros). Whether or not this is useful is somewhat dependent on compile time costs for macros vs code, and how small the list operations are in code size (ie: are they always inlined, or is it useful to be able to have a single instance of them). With the linux model, this can be determined at any time (by the compiler, or by the linked list library by changing it a bit), with the bsd model it is somewhat more difficult to make work (one could possibly do this by passing in the offset of the list_node structure to functions).
But list operation are so short and simple there's no benefit (especially if using the BSD approach) to generating and invoking functions. It just adds complexity.
If I had to guess, and based on memory (I first learned C programming by reading Linux and GNU project code), things ended up the way they are because like many early C projects Linux took the road of writing subsystem-specific list implementations using C function interfaces. Over time these interfaces were incrementally unified and improved, the quasi-generic implementations made more type-safe using the container_of and related constructs.
<sys/queue.h> seems to have been the product of a seasoned kernel hacker who took the opportunities provided by the huge 4.4BSD refactor to create and push a single, unified approach to be used across the kernel.
The list operations themselves (iterating, adding list nodes, removing list nodes) are all type safe (and can be placed in normal functions), the piece that gets funky is only examining the element content (which uses `container_of`).
There's no reason to speculate on the origin of the the bsd and linux approaches here, and the speculation given is highly questionable.