Basically, i am trying to avoid IoAllocateMDL and IoFreeMDL for each call to WskSendTo() function which takes WSK_BUF. Please advise me on this.
This works fine. Winsock itself does this for built-in TCP/UDP/RAW sockets.
I got one more question is WskSendTo() sends packets sequentially?
Assuming you’re sending them all to the same socket, precisely-speaking, the answer is no. But in practice, the answer is yes.
If the datagrams are all going to the same socket, then most of the time, they’ll be processed in order. But it’s possible for a WFP callout or NDIS filter driver to pluck out a single unlucky datagram and delay it. We don’t encourage them to do that, since packet reordering within a socket is usually bad for perf, so most don’t do this. So it’s not completely crazy for your application to require previous transmits to be completed before sending the next – especially if you have enough space in the ringbuffer to hide occasional small delays.
If you’re shipping your product on millions of arbitrary machines, you’ll discover an annoying gotcha: on occasion, NIC drivers will completely lose an NBL. This will eventually result in some sort of bugcheck (usually 0x9F), but until then, the system might sort of limp along in a seemingly-normal state. If you rely on completions to come back, you’ll get bitten hard if the NIC driver loses one of your NBLs. Your datapath will seize up, and customers will of course blame you, since your feature is likely to be the first user-visible symptom to appear. To defend against this, I suggest adding some careful counters & bookkeeping to know when a completion is taking an unreasonable time. If you’re only shipping your product on a few machines, or machines with carefully-vetted NIC drivers, this won’t be as much of a problem.
Also, if you’re still anxious about requiring in-order completion, it’s probably not too crazy difficult code or bad for perf to add the ability to use buffers out-of-order. (This is what Winsock does for the built-in TCP/UDP/RAW sockets). You can keep a freelist of idle buffers, and fill the ring with buffer indexes. Or similar schemes. This means that if someone does lose a buffer, your pool of available buffers will shrink a bit, but you won’t completely seize up. You don’t have to do this, but it might help you sleep better.