-
Notifications
You must be signed in to change notification settings - Fork 398
Hck rss bsod work in progress #1333
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
8f385f5
37aed71
8fa55ef
f8aa83d
42722f7
c850c5c
2dbfe47
87c7d3d
c21810c
8498ea9
4f54424
1a0a550
0cb024d
f378d0f
a1f5542
f7f42c9
6dd6d41
8a28663
69af2e6
27de6a4
653784e
3805b40
febd004
0dc95e7
e1e0236
c2d4571
3529450
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,9 +3,14 @@ | |
#include "ParaNdis-AbstractPath.h" | ||
#include "ParaNdis_GuestAnnounce.h" | ||
#include "ParaNdis_LockFreeQueue.h" | ||
#include "ParaNdis_DebugHistory.h" | ||
|
||
/* Must be a power of 2 */ | ||
#define PARANDIS_TX_LOCK_FREE_QUEUE_DEFAULT_SIZE 2048 | ||
#define NBL_MAINTAIN_HISTORY 0 | ||
#define NBL_CHAINS 1 | ||
#define SPAWN_TX_PROCESS_FROM_SEND_PATH 1 | ||
#define REPAIR_CHAIN (NBL_CHAINS && 1) | ||
|
||
/* the maximum number of pages that a single network packet can span. | ||
refer linux kernel code #define MAX_SKB_FRAGS (65536/PAGE_SIZE + 1), */ | ||
|
@@ -105,6 +110,33 @@ class CNB : public CNdisAllocatableViaHelper<CNB> | |
DECLARE_CNDISLIST_ENTRY(CNB); | ||
}; | ||
|
||
typedef struct _tChainOfNbls | ||
{ | ||
CNdisRefCounter m_NumChained; | ||
CNdisRefCounter m_NumCompleted; | ||
CNBL *m_FirstInChain; | ||
} CChainOfNbls; | ||
|
||
class NBLHistory : public CNdisAllocatable<NBLHistory, 'NBLH'> | ||
{ | ||
DECLARE_CNDISLIST_ENTRY(NBLHistory); | ||
|
||
public: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. in this case there should be extra line before access specifiers |
||
NBLHistory(LPCSTR Func, LPCSTR Title, LPCSTR ParameterMeaning, PVOID Parameter, LPCSTR ValueMeaning, ULONG Value); | ||
|
||
protected: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same here There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @Jedoku is this behavior configurable? I ask because this does not make too much sense. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's configured in .clang-format There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @Jedoku If there is an option "don't mind" this will not request any change, correct? Is it? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
ULONGLONG m_Timestamp; | ||
LPCSTR m_Function; | ||
LPCSTR m_Title; | ||
LPCSTR m_ParameterMeaning; | ||
PVOID m_Parameter; | ||
LPCSTR m_ValueMeaning; | ||
ULONG m_Value; | ||
ULONG m_CurrentCPU; | ||
}; | ||
|
||
typedef CNdisList<NBLHistory, CLockedAccess, CNonCountingObject> CHistoryList; | ||
|
||
class CNBL : public CNdisAllocatableViaHelper<CNBL>, public CRefCountingObject, public CAllocationHelper<CNB> | ||
{ | ||
public: | ||
|
@@ -129,6 +161,90 @@ class CNBL : public CNdisAllocatableViaHelper<CNBL>, public CRefCountingObject, | |
{ | ||
return (ParsePriority() && ParseBuffers() && ParseOffloads()); | ||
} | ||
#if NBL_CHAINS | ||
void Die() | ||
{ | ||
// RtlFailFast(FAST_FAIL_RANGE_CHECK_FAILURE); | ||
DbgBreakPoint(); | ||
} | ||
void SetInChain(PNET_BUFFER_LIST FirstInChain) | ||
{ | ||
if (FirstInChain != m_NBL) | ||
{ | ||
m_Chain.m_FirstInChain = (CNBL *)FirstInChain->Scratch; | ||
LONG serial = m_Chain.m_FirstInChain->m_Chain.m_NumChained.AddRef(); | ||
m_Chain.m_FirstInChain->AddRef(); | ||
// set the serial number in chain for information | ||
m_Chain.m_NumChained.AddRef(serial); | ||
} | ||
} | ||
void UnsetInChain() | ||
{ | ||
// the NBL was failed mapping, if does not go | ||
// to transmit path | ||
ParaNdis_DebugHistory(this, | ||
eHistoryLogOperation::hopSendComplete, | ||
m_NBL, | ||
!m_Chain.m_FirstInChain, | ||
m_NBL->Status, | ||
GetCurrentRefCounterUnsafe()); | ||
if (m_Chain.m_FirstInChain) | ||
{ | ||
m_Chain.m_FirstInChain->m_Chain.m_NumChained.Release(); | ||
// the head of chain will be released in the destructor | ||
} | ||
} | ||
void CompleteInChain() | ||
{ | ||
auto head = m_Chain.m_FirstInChain; | ||
if (head) | ||
{ | ||
if (m_NBL) | ||
{ | ||
// Detach NBL from chained CNBL and chain it the end | ||
// of the chain started from m_NBL of the first CNBL | ||
// The NBL is fully completed, so STATUS_SUCCESS | ||
SetStatus(NDIS_STATUS_SUCCESS); | ||
auto rawNbl = DetachInternalObject(); | ||
// save the serial number in chain | ||
rawNbl->Scratch = (PVOID)(LONG)m_Chain.m_NumChained; | ||
PNET_BUFFER_LIST *next = &NET_BUFFER_LIST_NEXT_NBL(head->m_NBL); | ||
|
||
// Attach to the tail of NBLs atomically | ||
while (InterlockedCompareExchangePointer((PVOID *)next, rawNbl, nullptr)) | ||
{ | ||
next = &NET_BUFFER_LIST_NEXT_NBL(*next); | ||
} | ||
} | ||
LONG completed = head->m_Chain.m_NumCompleted.AddRef(); | ||
ParaNdis_DebugHistory(this, | ||
eHistoryLogOperation::hopSendCompleteChain, | ||
head, | ||
completed, | ||
m_Chain.m_NumChained, | ||
head->GetCurrentRefCounterUnsafe()); | ||
AddHistory(__FUNCTION__, "", "Head", head, "Completed", completed); | ||
if (head->m_Chain.m_NumChained < completed) | ||
{ | ||
// this is a fatal problem, probably caused by | ||
// double completion, may cause to list corruption | ||
// TODO: assertion?? | ||
Die(); | ||
} | ||
} | ||
} | ||
#else | ||
void SetInChain(PNET_BUFFER_LIST FirstInChain) | ||
{ | ||
UNREFERENCED_PARAMETER(FirstInChain); | ||
} | ||
void UnsetInChain() | ||
{ | ||
} | ||
void CompleteInChain() | ||
{ | ||
} | ||
#endif | ||
void StartMapping(); | ||
void RegisterMappedNB(CNB *NB); | ||
bool MappingSucceeded() | ||
|
@@ -150,11 +266,6 @@ class CNBL : public CNdisAllocatableViaHelper<CNBL>, public CRefCountingObject, | |
return !m_Buffers.IsEmpty(); | ||
} | ||
|
||
bool HaveDetachedBuffers() | ||
{ | ||
return m_MappedBuffersDetached != 0; | ||
} | ||
|
||
PNET_BUFFER_LIST DetachInternalObject(); | ||
// TODO: Needs review | ||
void NBComplete(); | ||
|
@@ -230,6 +341,10 @@ class CNBL : public CNdisAllocatableViaHelper<CNBL>, public CRefCountingObject, | |
m_TransferSize += ChunkSize; | ||
} | ||
} | ||
bool HasNBL() const | ||
{ | ||
return m_NBL != nullptr; | ||
} | ||
ULONG NumberOfBuffers() const | ||
{ | ||
return m_BuffersNumber; | ||
|
@@ -238,7 +353,18 @@ class CNBL : public CNdisAllocatableViaHelper<CNBL>, public CRefCountingObject, | |
{ | ||
return m_ParentTXPath; | ||
} | ||
|
||
#if NBL_MAINTAIN_HISTORY | ||
void AddHistory(LPCSTR Func, | ||
LPCSTR Title, | ||
LPCSTR ParameterMeaning = NULL, | ||
PVOID Parameter = NULL, | ||
LPCSTR ValueMeaning = NULL, | ||
ULONG Value = NULL); | ||
#else | ||
void AddHistory(...) | ||
{ | ||
} | ||
#endif | ||
private: | ||
virtual void OnLastReferenceGone() override; | ||
|
||
|
@@ -276,6 +402,7 @@ class CNBL : public CNdisAllocatableViaHelper<CNBL>, public CRefCountingObject, | |
// align storage for CNB on pointer size boundary and provide enough room for it | ||
ULONG_PTR m_CNB_Storage[(sizeof(CNB) + sizeof(ULONG_PTR) - 1) / sizeof(ULONG_PTR)]; | ||
bool m_HaveFailedMappings = false; | ||
bool m_AllNBCompleted = false; | ||
|
||
CNdisList<CNB, CRawAccess, CNonCountingObject> m_Buffers; | ||
|
||
|
@@ -297,6 +424,9 @@ class CNBL : public CNdisAllocatableViaHelper<CNBL>, public CRefCountingObject, | |
#endif | ||
CAllocationHelper<CNB> *m_NBAllocator; | ||
|
||
CChainOfNbls m_Chain = {}; | ||
CHistoryList m_History; | ||
|
||
CNBL(const CNBL &) = delete; | ||
CNBL &operator=(const CNBL &) = delete; | ||
|
||
|
@@ -363,6 +493,8 @@ class CParaNdisTX : public CParaNdisTemplatePath<CTXVirtQueue>, public CNdisAllo | |
|
||
bool SendMapped(bool IsInterrupt, CRawCNBLList &toWaitingList); | ||
|
||
void DropAllNBls(CRawCNBLList &Completed, NDIS_STATUS Status); | ||
|
||
bool FillQueue(); | ||
|
||
void PostProcessPendingTask(CRawCNBList &toFree, CRawCNBLList &completed); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please submit this as a separate PR. It can already be merged and make future review easier.
Thanks!