Perform floating point operations in a NDIS LWF driver?

Dear all,

I am quite new to Windows driver developing. I am struggling with the calculation of the required transmission time of a single NB within a NDIS LWF driver. In particular, I am struggling with the usage of DOUBLE values and the conversion to a LONGLONG:

  • Within the FilterAttach() function I save the pFiler->XmitLinkSpeed in [bytes per second]

  • Calculation of the transmission time:
    ULONG PacketSize = NET_BUFFER_DATA_LENGTH(pNb);
    DOUBLE XmitTimeInSec = (DOUBLE)PacketSize / LinkSpeed;
    LONGLONG XmitTimeIn100NanoSecInterval = (LONGLONG) (XmitTimeInSec * 1000 /* ms */ * 1000 /* usec */ * 10 /* 100-nsec intervals */);

The error messages reported by the compiler are as follows:

  • error LNK2019: unresolved external symbol __ftol2 referenced in function _DequeueNb@8
  • error LNK2001: unresolved external symbol __fltused

Is it possible to perform floating point operations within a NDIS LWF driver?
How to convert a DOUBLE to a LONGLONG?

Thanks,
sk

Hmm, right now I found the following link https://msdn.microsoft.com/en-us/library/windows/hardware/ff570020(v=vs.85).aspx which states:

“Do not use floating-point operations in kernel mode. If you attempt such operations, a fatal error will occur.”

Hmm, is there any way to calculate the time when the last bit of a NB has been transmitted? I don’t want to rely on the SendNetBufferListsComplete() callback function since it will be not called immediately after the NBL with the NB has been successfully transmitted.

Thanks again,
sk

Your time expression reduces to

LONGLONG XmitTimeIn100NanoSecInterval = ((PacketSize / LinkSpeed) * 1000 * 1000 * 10);

where LinkSpeed is presumably larger than PacketSize, so that the integer division results in 0.

Notice however that the RHS can also be expressed as ((PacketSize * 1000 * 1000 * 10) / LinkSpeed).

Provided

a) (PacketSize * 1000 * 1000 * 10) doesn’t overflow a LONGLONG, and
b) LinkSpeed isn’t larger than (PacketSize * 1000 * 1000 * 10),

you now have an estimate of the time required which doesn’t require floating point.

You may also wish to round it up as well (exercise for the reader).

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:bounce-581559-
xxxxx@lists.osr.com] On Behalf Of xxxxx@siemens.com
Sent: 28 April 2015 12:34
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Perform floating point operations in a NDIS LWF
driver?

Hmm, right now I found the following link
https://msdn.microsoft.com/en-
us/library/windows/hardware/ff570020(v=vs.85).aspx which states:

“Do not use floating-point operations in kernel mode. If you attempt
such operations, a fatal error will occur.”

Hmm, is there any way to calculate the time when the last bit of a NB
has been transmitted? I don’t want to rely on the
SendNetBufferListsComplete() callback function since it will be not
called immediately after the NBL with the NB has been successfully
transmitted.
This email message has been delivered safely and archived online by Mimecast.

For more information please visit http://www.mimecast.com

Thanks David, that works like a charm since in my case all preconditions are fulfilled.

Btw: What’s the reason that floating point operations are not supported within a NDIS filter driver?

> -----Original Message-----

From: xxxxx@lists.osr.com [mailto:bounce-581563-
xxxxx@lists.osr.com] On Behalf Of xxxxx@siemens.com
Sent: 28 April 2015 13:28
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Perform floating point operations in a NDIS LWF
driver?

Thanks David, that works like a charm since in my case all
preconditions are fulfilled.

Glad it helped.

Btw: What’s the reason that floating point operations are not supported
within a NDIS filter driver?

I have no idea; I’ve never had to deal with one. Someone else here may be able to
enlighten us.

Floating point operations in the kernel can be performed, but you may have to take
special care. See

https://msdn.microsoft.com/en-us/library/windows/hardware/ff545910.aspx

and

https://msdn.microsoft.com/en-us/library/windows/hardware/ff565388.aspx
This email message has been delivered safely and archived online by Mimecast.

For more information please visit http://www.mimecast.com

xxxxx@siemens.com wrote:

Thanks David, that works like a charm since in my case all preconditions are fulfilled.

Btw: What’s the reason that floating point operations are not supported within a NDIS filter driver?

In order to save time, the floating point CPU state is not saved and
restored on a kernel-mode thread switch. If you trash an FPU register,
you are damaging some other process. This dates back to the 1990s when
the FPU was a separate chip and communication to it was VERY expensive.

There are kernel routines to save and restore the state manually, but I
don’t know if they are allowed in an NDIS driver.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.