Advertisement
Guest User

Tim

a guest
Dec 17th, 2009
839
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.65 KB | None | 0 0
  1. Files winaoe-0.97g/bin/aoe.exe and winaoe-0.97g.deadlock_fix.1/bin/aoe.exe differ
  2. Files winaoe-0.97g/bin/aoe32.sys and winaoe-0.97g.deadlock_fix.1/bin/aoe32.sys differ
  3. Files winaoe-0.97g/bin/aoe64.sys and winaoe-0.97g.deadlock_fix.1/bin/aoe64.sys differ
  4. diff -ru winaoe-0.97g/src/aoe.c winaoe-0.97g.deadlock_fix.1/src/aoe.c
  5. --- winaoe-0.97g/src/aoe.c 2008-03-12 00:23:04.000000000 -0500
  6. +++ winaoe-0.97g.deadlock_fix.1/src/aoe.c 2008-12-09 14:29:05.112016000 -0600
  7. @@ -111,14 +111,20 @@
  8. } DISKSEARCH, *PDISKSEARCH;
  9.  
  10. BOOLEAN Stop = FALSE;
  11. -KSPIN_LOCK SpinLock;
  12. +static KSPIN_LOCK SpinLock;
  13. +static KSPIN_LOCK ReplySpinLock;
  14. KEVENT ThreadSignalEvent;
  15. PTAG TagList = NULL;
  16. PTAG TagListLast = NULL;
  17. PTAG ProbeTag = NULL;
  18. +PTAG ReplyTagListLast = NULL;
  19. +PTAG ReplyTagListHead = NULL;
  20. PDISKSEARCH DiskSearchList = NULL;
  21. LONG OutstandingTags = 0;
  22. HANDLE ThreadHandle;
  23. +UCHAR GlobalSourceMac[6];
  24. +
  25. +
  26.  
  27. NTSTATUS STDCALL AoEStart() {
  28. NTSTATUS Status;
  29. @@ -145,6 +151,7 @@
  30. ProbeTag->PacketData->Count = 1;
  31.  
  32. KeInitializeSpinLock(&SpinLock);
  33. + KeInitializeSpinLock(&ReplySpinLock);
  34. KeInitializeEvent(&ThreadSignalEvent, SynchronizationEvent, FALSE);
  35.  
  36. InitializeObjectAttributes(&ObjectAttributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);
  37. @@ -240,7 +247,7 @@
  38. Timeout.QuadPart = -500000LL; // 500.000 * 100ns = 50.000.000 ns = 50ms
  39. KeWaitForSingleObject(&DeviceExtension->Disk.SearchEvent, Executive, KernelMode, FALSE, &Timeout);
  40. if (Stop) {
  41. - DbgPrint("AoESearchBootDrive cancled\n");
  42. + DbgPrint("AoESearchBootDrive canceled\n");
  43. return FALSE;
  44. }
  45.  
  46. @@ -513,27 +520,81 @@
  47. return STATUS_PENDING;
  48. }
  49.  
  50. -NTSTATUS STDCALL AoEReply(IN PUCHAR SourceMac, IN PUCHAR DestinationMac, IN PUCHAR Data, IN UINT DataSize) {
  51. +
  52. +
  53. +
  54. +// Call from protocolReceive/NDIS to add packets to receive queue
  55. +NTSTATUS STDCALL AoEReplyQueue(IN PUCHAR SourceMac, IN PUCHAR DestinationMac, IN PUCHAR Data, IN UINT DataSize) {
  56. PAOE Reply = (PAOE)Data;
  57. LONGLONG LBASize;
  58. - PTAG Tag;
  59. + PTAG ReplyTag;
  60. KIRQL Irql;
  61. - BOOLEAN Found = FALSE;
  62. - LARGE_INTEGER CurrentTime;
  63.  
  64. if (!Reply->ResponseFlag) return STATUS_SUCCESS;
  65.  
  66. +
  67. + // Special case for AoE probe response
  68. if (ProbeTag->Id == Reply->Tag) {
  69. RtlCopyMemory(&LBASize, &Reply->Data[200], sizeof(LONGLONG));
  70. BusAddTarget(DestinationMac, SourceMac, ntohs(Reply->Major), Reply->Minor, LBASize);
  71. return STATUS_SUCCESS;
  72. }
  73.  
  74. +
  75. + // allocate storage
  76. + if ((ReplyTag = (PTAG)ExAllocatePool(NonPagedPool, sizeof(TAG))) == NULL) {
  77. + DbgPrint("AoERequest ExAllocatePool ReplyTag\n");
  78. + return STATUS_INSUFFICIENT_RESOURCES;
  79. + }
  80. + RtlZeroMemory(ReplyTag, sizeof(TAG));
  81. + // - not using all the TAG fields, just PacketData, PacketSize, Next, and Previous
  82. + ReplyTag->PacketSize = DataSize;
  83. + if ((ReplyTag->PacketData = (PAOE)ExAllocatePool(NonPagedPool, ReplyTag->PacketSize)) == NULL) {
  84. + DbgPrint("AoERequest ExAllocatePool ReplyTag->PacketData\n");
  85. + ExFreePool(ReplyTag);
  86. + return STATUS_INSUFFICIENT_RESOURCES;
  87. + }
  88. +
  89. + // copy packet data to list item
  90. + RtlCopyMemory(ReplyTag->PacketData, Reply, ReplyTag->PacketSize);
  91. +
  92. + // AoEProcessReply needs the SourceMac, so save it
  93. + RtlCopyMemory(GlobalSourceMac, SourceMac, 6);
  94. +
  95. + // add to the end of the reply list
  96. + KeAcquireSpinLock(&ReplySpinLock, &Irql);
  97. + if (ReplyTagListLast == NULL) {
  98. + ReplyTagListHead = ReplyTag;
  99. + } else {
  100. + ReplyTagListLast->Next = ReplyTag;
  101. + ReplyTag->Previous = ReplyTagListLast;
  102. + ReplyTag->Next = NULL;
  103. + }
  104. + ReplyTagListLast = ReplyTag;
  105. + KeReleaseSpinLock(&ReplySpinLock, Irql);
  106. +
  107. + // tell Thread we have a reply
  108. + KeSetEvent(&ThreadSignalEvent, 0, FALSE);
  109. + return STATUS_SUCCESS;
  110. +}
  111. +
  112. +
  113. +// changed this to process receive list; call from Thread before processing sends
  114. +NTSTATUS STDCALL AoEProcessReply(IN PUCHAR Data, IN UINT DataSize) {
  115. + PAOE Reply = (PAOE) Data;
  116. + LONGLONG LBASize;
  117. + PTAG Tag;
  118. + KIRQL Irql;
  119. + BOOLEAN Found = FALSE;
  120. + LARGE_INTEGER CurrentTime;
  121. +
  122. +
  123. KeAcquireSpinLock(&SpinLock, &Irql);
  124. if (TagList == NULL) {
  125. KeReleaseSpinLock(&SpinLock, Irql);
  126. return STATUS_SUCCESS;
  127. }
  128. + // see if we need this packet
  129. Tag = TagList;
  130. while (Tag != NULL) {
  131. if ((Tag->Id == Reply->Tag) && (Tag->PacketData->Major == Reply->Major) && (Tag->PacketData->Minor == Reply->Minor)) {
  132. @@ -546,24 +607,29 @@
  133. KeReleaseSpinLock(&SpinLock, Irql);
  134. return STATUS_SUCCESS;
  135. } else {
  136. + // we need this packet, remove from TagList, and decrement count
  137. if (Tag->Previous == NULL) TagList = Tag->Next;
  138. else Tag->Previous->Next = Tag->Next;
  139. if (Tag->Next == NULL) TagListLast = Tag->Previous;
  140. else Tag->Next->Previous = Tag->Previous;
  141. OutstandingTags--;
  142. if (OutstandingTags < 0) DbgPrint("!!OutstandingTags < 0 (AoEReply)!!\n");
  143. - KeSetEvent(&ThreadSignalEvent, 0, FALSE);
  144. }
  145. KeReleaseSpinLock(&SpinLock, Irql);
  146.  
  147. + // get MAC from a global
  148. if (RtlCompareMemory(Tag->DeviceExtension->Disk.ServerMac, "\xff\xff\xff\xff\xff\xff", 6) == 6) {
  149. - RtlCopyMemory(Tag->DeviceExtension->Disk.ServerMac, SourceMac, 6);
  150. - DbgPrint("Major: %d minor: %d found on server %02x:%02x:%02x:%02x:%02x:%02x\n", Tag->DeviceExtension->Disk.Major, Tag->DeviceExtension->Disk.Minor, SourceMac[0], SourceMac[1], SourceMac[2], SourceMac[3], SourceMac[4], SourceMac[5]);
  151. + RtlCopyMemory(Tag->DeviceExtension->Disk.ServerMac, GlobalSourceMac, 6);
  152. + DbgPrint("Major: %d minor: %d found on server %02x:%02x:%02x:%02x:%02x:%02x\n", Tag->DeviceExtension->Disk.Major, Tag->DeviceExtension->Disk.Minor,
  153. + GlobalSourceMac[0], GlobalSourceMac[1], GlobalSourceMac[2], GlobalSourceMac[3], GlobalSourceMac[4], GlobalSourceMac[5]);
  154. }
  155.  
  156. KeQuerySystemTime(&CurrentTime);
  157. + // timeout -= (timeout - delta time) / 1024
  158. Tag->DeviceExtension->Disk.Timeout -= (ULONG)((Tag->DeviceExtension->Disk.Timeout - (CurrentTime.QuadPart - Tag->FirstSendTime.QuadPart)) / 1024);
  159. if (Tag->DeviceExtension->Disk.Timeout > 100000000) Tag->DeviceExtension->Disk.Timeout = 100000000;
  160. + // min timeout = 7 msec
  161. + //if (Tag->DeviceExtension->Disk.Timeout < 70000) Tag->DeviceExtension->Disk.Timeout = 70000;
  162.  
  163. switch (Tag->Type) {
  164. case SearchDriveType:
  165. @@ -615,7 +681,6 @@
  166. break;
  167. }
  168.  
  169. - KeSetEvent(&ThreadSignalEvent, 0, FALSE);
  170. ExFreePool(Tag->PacketData);
  171. ExFreePool(Tag);
  172. return STATUS_SUCCESS;
  173. @@ -629,14 +694,15 @@
  174. LARGE_INTEGER Timeout, CurrentTime, ProbeTime, ReportTime;
  175. ULONG NextTagId = 1;
  176. PTAG Tag;
  177. - KIRQL Irql;
  178. + PTAG Next=NULL;
  179. + KIRQL Irql, Irq2;
  180. ULONG Sends = 0;
  181. ULONG Resends = 0;
  182. ULONG ResendFails = 0;
  183. ULONG Fails = 0;
  184. ULONG RequestTimeout = 0;
  185.  
  186. - DbgPrint("Thread\n");
  187. + DbgPrint("Thread - entry\n");
  188. ReportTime.QuadPart = 0LL;
  189. ProbeTime.QuadPart = 0LL;
  190.  
  191. @@ -652,7 +718,7 @@
  192.  
  193. KeQuerySystemTime(&CurrentTime);
  194. if (CurrentTime.QuadPart > (ReportTime.QuadPart + 10000000LL)) {
  195. -// DbgPrint("Sends: %d Resends: %d ResendFails: %d Fails: %d OutstandingTags: %d RequestTimeout: %d\n", Sends, Resends, ResendFails, Fails, OutstandingTags, RequestTimeout);
  196. + DbgPrint("Sends: %d Resends: %d ResendFails: %d Fails: %d OutstandingTags: %d RequestTimeout: %d\n", Sends, Resends, ResendFails, Fails, OutstandingTags, RequestTimeout);
  197. Sends = 0;
  198. Resends = 0;
  199. ResendFails = 0;
  200. @@ -660,6 +726,7 @@
  201. KeQuerySystemTime(&ReportTime);
  202. }
  203.  
  204. + // send the probe every 100 seconds
  205. if (CurrentTime.QuadPart > (ProbeTag->SendTime.QuadPart + 100000000LL)) {
  206. ProbeTag->Id = NextTagId++;
  207. if (NextTagId == 0) NextTagId++;
  208. @@ -668,6 +735,21 @@
  209. KeQuerySystemTime(&ProbeTag->SendTime);
  210. }
  211.  
  212. +
  213. + // process the reply list, deleting each item after processing
  214. + KeAcquireSpinLock(&ReplySpinLock, &Irq2);
  215. + for (Tag = ReplyTagListHead; Tag != NULL; Tag=Next) {
  216. + AoEProcessReply ((PUCHAR) Tag->PacketData, Tag->PacketSize);
  217. + Next= Tag->Next;
  218. + ExFreePool (Tag->PacketData);
  219. + ExFreePool(Tag);
  220. + }
  221. + ReplyTagListHead = NULL;
  222. + ReplyTagListLast = NULL;
  223. + KeReleaseSpinLock(&ReplySpinLock, Irq2);
  224. +
  225. +
  226. + // process the Tag list
  227. KeAcquireSpinLock(&SpinLock, &Irql);
  228. if (TagList == NULL) {
  229. KeReleaseSpinLock(&SpinLock, Irql);
  230. @@ -676,6 +758,7 @@
  231. Tag = TagList;
  232. while (Tag != NULL) {
  233. RequestTimeout = Tag->DeviceExtension->Disk.Timeout;
  234. + // if this is a new packet to send
  235. if (Tag->Id == 0) {
  236. if (OutstandingTags <= 64) {
  237. //if (OutstandingTags <= 102400) {
  238. @@ -687,20 +770,25 @@
  239. KeQuerySystemTime(&Tag->FirstSendTime);
  240. KeQuerySystemTime(&Tag->SendTime);
  241. OutstandingTags++;
  242. - Sends++;
  243. + Sends++;
  244. } else {
  245. Fails++;
  246. Tag->Id = 0;
  247. break;
  248. }
  249. }
  250. + // else this is a previously sent packet; see if we need to re-send it
  251. } else {
  252. KeQuerySystemTime(&CurrentTime);
  253. + // if we've waited longer than the 2*timeout, resend packet, and raise the timeout value a little
  254. if (CurrentTime.QuadPart > (Tag->SendTime.QuadPart + (LONGLONG)(Tag->DeviceExtension->Disk.Timeout * 2))) {
  255. if (ProtocolSend(Tag->DeviceExtension->Disk.ClientMac, Tag->DeviceExtension->Disk.ServerMac, (PUCHAR)Tag->PacketData, Tag->PacketSize, Tag)) {
  256. KeQuerySystemTime(&Tag->SendTime);
  257. + // timeout += timeout/1000
  258. Tag->DeviceExtension->Disk.Timeout += Tag->DeviceExtension->Disk.Timeout / 1000;
  259. if (Tag->DeviceExtension->Disk.Timeout > 100000000) Tag->DeviceExtension->Disk.Timeout = 100000000;
  260. + // min timeout = 7 msec
  261. + //if (Tag->DeviceExtension->Disk.Timeout < 70000) Tag->DeviceExtension->Disk.Timeout = 70000;
  262. Resends++;
  263. } else {
  264. ResendFails++;
  265. diff -ru winaoe-0.97g/src/aoe.h winaoe-0.97g.deadlock_fix.1/src/aoe.h
  266. --- winaoe-0.97g/src/aoe.h 2008-02-19 08:46:08.000000000 -0600
  267. +++ winaoe-0.97g.deadlock_fix.1/src/aoe.h 2008-12-04 17:50:30.376059800 -0600
  268. @@ -23,6 +23,7 @@
  269. #include "portable.h"
  270. #include "driver.h"
  271.  
  272. +
  273. #define htons(x) (USHORT)((((x) << 8) & 0xff00) | (((x) >> 8) & 0xff))
  274. #define ntohs(x) (USHORT)((((x) << 8) & 0xff00) | (((x) >> 8) & 0xff))
  275.  
  276. @@ -30,7 +31,8 @@
  277.  
  278. BOOLEAN STDCALL AoESearchDrive(IN PDEVICEEXTENSION DeviceExtension);
  279. NTSTATUS STDCALL AoERequest(IN PDEVICEEXTENSION DeviceExtension, IN REQUESTMODE Mode, IN LONGLONG StartSector, IN ULONG SectorCount, IN PUCHAR Buffer, IN PIRP Irp);
  280. -NTSTATUS STDCALL AoEReply(IN PUCHAR SourceMac, IN PUCHAR DestinationMac, IN PUCHAR Data, IN UINT DataSize);
  281. +NTSTATUS STDCALL AoEReplyQueue(IN PUCHAR SourceMac, IN PUCHAR DestinationMac, IN PUCHAR Data, IN UINT DataSize);
  282. +NTSTATUS STDCALL AoEProcessReply(IN PUCHAR Data, IN UINT DataSize);
  283. VOID STDCALL AoEResetProbe();
  284.  
  285. #endif
  286. diff -ru winaoe-0.97g/src/debug.c winaoe-0.97g.deadlock_fix.1/src/debug.c
  287. --- winaoe-0.97g/src/debug.c 2008-02-19 08:46:08.000000000 -0600
  288. +++ winaoe-0.97g.deadlock_fix.1/src/debug.c 2008-12-03 12:51:37.992681100 -0600
  289. @@ -38,7 +38,7 @@
  290. } IRPLIST, *PIRPLIST;
  291.  
  292. PIRPLIST IrpList = NULL;
  293. -KSPIN_LOCK SpinLock;
  294. +static KSPIN_LOCK SpinLock;
  295. ULONG Number = 0;
  296.  
  297. extern int sprintf(char*, const char *, ...);
  298. diff -ru winaoe-0.97g/src/protocol.c winaoe-0.97g.deadlock_fix.1/src/protocol.c
  299. --- winaoe-0.97g/src/protocol.c 2008-02-19 08:46:08.000000000 -0600
  300. +++ winaoe-0.97g.deadlock_fix.1/src/protocol.c 2008-12-04 17:55:02.874315800 -0600
  301. @@ -71,7 +71,7 @@
  302. } BINDINGCONTEXT, *PBINDINGCONTEXT;
  303.  
  304. KEVENT ProtocolStopEvent;
  305. -KSPIN_LOCK SpinLock;
  306. +static KSPIN_LOCK SpinLock;
  307. PBINDINGCONTEXT BindingContextList = NULL;
  308. NDIS_HANDLE ProtocolHandle = NULL;
  309.  
  310. @@ -259,7 +259,7 @@
  311. } else {
  312. DbgPrint("ProtocolTransferDataComplete Header (back) Buffer == NULL\n");
  313. }
  314. - if (Header != NULL && Data != NULL) AoEReply(Header->SourceMac, Header->DestinationMac, Data, DataSize);
  315. + if (Header != NULL && Data != NULL) AoEReplyQueue(Header->SourceMac, Header->DestinationMac, Data, DataSize);
  316. if (Header != NULL) ExFreePool(Header);
  317. if (Data != NULL) ExFreePool(Data);
  318. NdisFreePacket(Packet);
  319. @@ -303,7 +303,7 @@
  320. if (ntohs(Header->Protocol) != AOEPROTOCOLID) return NDIS_STATUS_NOT_ACCEPTED;
  321.  
  322. if (LookaheadBufferSize == PacketSize) {
  323. - AoEReply(Header->SourceMac, Header->DestinationMac, LookAheadBuffer, PacketSize);
  324. + AoEReplyQueue(Header->SourceMac, Header->DestinationMac, LookAheadBuffer, PacketSize);
  325. return NDIS_STATUS_SUCCESS;
  326. }
  327.  
  328.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement