Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1354 lines
30 KiB

  1. /*++
  2. Copyright (c 1999 Microsoft Corporation
  3. Module Name:
  4. preftchp.h
  5. Abstract:
  6. This module contains the private definitions for the kernel mode
  7. prefetcher for optimizing demand paging. Page faults for a
  8. scenario are logged and the next time scenario starts, these pages
  9. are prefetched efficiently via asynchronous paging I/O.
  10. Author:
  11. Stuart Sechrest (stuartse)
  12. Chuck Lenzmeier (chuckl)
  13. Cenk Ergan (cenke)
  14. Revision History:
  15. --*/
  16. #ifndef _PREFTCHP_H
  17. #define _PREFTCHP_H
  18. //
  19. // Define tags used in prefetcher routines.
  20. //
  21. #define CCPF_PREFETCHER_TAG 'fPcC'
  22. #define CCPF_ALLOC_SCENARIO_TAG 'SPcC'
  23. #define CCPF_ALLOC_TRACE_TAG 'TPcC'
  24. #define CCPF_ALLOC_TRCBUF_TAG 'BPcC'
  25. #define CCPF_ALLOC_SECTTBL_TAG 'sPcC'
  26. #define CCPF_ALLOC_TRCDMP_TAG 'DPcC'
  27. #define CCPF_ALLOC_QUERY_TAG 'qPcC'
  28. #define CCPF_ALLOC_FILENAME_TAG 'FPcC'
  29. #define CCPF_ALLOC_CONTEXT_TAG 'CPcC'
  30. #define CCPF_ALLOC_INTRTABL_TAG 'IPcC'
  31. #define CCPF_ALLOC_PREFSCEN_TAG 'pPcC'
  32. #define CCPF_ALLOC_BOOTWRKR_TAG 'wPcC'
  33. #define CCPF_ALLOC_VOLUME_TAG 'vPcC'
  34. #define CCPF_ALLOC_READLIST_TAG 'LPcC'
  35. #define CCPF_ALLOC_METADATA_TAG 'MPcC'
  36. //
  37. // Whether the scenario type is for a system-wide scenario, meaning that
  38. // only it can be active while running.
  39. //
  40. #define CCPF_IS_SYSTEM_WIDE_SCENARIO_TYPE(ScenarioType) \
  41. ((ScenarioType) == PfSystemBootScenarioType)
  42. //
  43. // In the kernel, we have to look for named objects under this
  44. // directory for them to visible to Win32 prefetcher service.
  45. //
  46. #define CCPF_BASE_NAMED_OBJ_ROOT_DIR L"\\BaseNamedObjects"
  47. //
  48. // This is the invalid index value used with section tables.
  49. //
  50. #define CCPF_INVALID_TABLE_INDEX (-1)
  51. //
  52. // This is the max number of file metadata that NTFS can prefetch
  53. // at a time.
  54. //
  55. #define CCPF_MAX_FILE_METADATA_PREFETCH_COUNT 0x300
  56. //
  57. // Define structure to hold prefetcher parameters state.
  58. //
  59. typedef struct _CCPF_PREFETCHER_PARAMETERS {
  60. //
  61. // This is the named event that is used to signal the service that
  62. // parameters have been updated.
  63. //
  64. HANDLE ParametersChangedEvent;
  65. //
  66. // This is the registry key containing prefetch parameters.
  67. //
  68. HANDLE ParametersKey;
  69. //
  70. // Fields used in registering for change notify on parameters
  71. // registry key.
  72. //
  73. IO_STATUS_BLOCK RegistryWatchIosb;
  74. WORK_QUEUE_ITEM RegistryWatchWorkItem;
  75. ULONG RegistryWatchBuffer;
  76. //
  77. // System wide prefetching parameters. When using any parameters
  78. // whose update may cause problems [e.g. strings], get the
  79. // ParametersLock shared. When you need to update Parameters,
  80. // after getting the ParametersLock exclusive, bump
  81. // ParametersVersion before updating parameters.
  82. //
  83. PF_SYSTEM_PREFETCH_PARAMETERS Parameters;
  84. ERESOURCE ParametersLock;
  85. LONG ParametersVersion;
  86. //
  87. // Prefixes to registry values for different scenario types.
  88. //
  89. WCHAR *ScenarioTypePrefixes[PfMaxScenarioType];
  90. //
  91. // This is set to InitSafeBootMode during initialization.
  92. //
  93. ULONG SafeBootMode;
  94. } CCPF_PREFETCHER_PARAMETERS, *PCCPF_PREFETCHER_PARAMETERS;
  95. //
  96. // Define structure to hold prefetcher's global state.
  97. //
  98. typedef struct _CCPF_PREFETCHER_GLOBALS {
  99. //
  100. // List of active traces and the lock to protect it. The number
  101. // of items on this list is a global, since it is used by other
  102. // kernel components to make a fast check.
  103. //
  104. LIST_ENTRY ActiveTraces;
  105. KSPIN_LOCK ActiveTracesLock;
  106. //
  107. // Pointer to the global trace if one is active. While there is a
  108. // global trace active we don't trace & prefetch other scenarios.
  109. // Boot tracing is an example of global trace.
  110. //
  111. struct _CCPF_TRACE_HEADER *SystemWideTrace;
  112. //
  113. // List and number of saved completed prefetch traces and lock to
  114. // protect it.
  115. //
  116. LIST_ENTRY CompletedTraces;
  117. FAST_MUTEX CompletedTracesLock;
  118. LONG NumCompletedTraces;
  119. //
  120. // This is the named event that is used to signal the service that
  121. // there are traces ready for it to get.
  122. //
  123. HANDLE CompletedTracesEvent;
  124. //
  125. // Prefetcher parameters.
  126. //
  127. CCPF_PREFETCHER_PARAMETERS Parameters;
  128. } CCPF_PREFETCHER_GLOBALS, *PCCPF_PREFETCHER_GLOBALS;
  129. //
  130. // Reference count structure.
  131. //
  132. typedef struct _CCPF_REFCOUNT {
  133. //
  134. // When initialized or reset, this reference count starts from
  135. // 1. When exclusive access is granted it stays at 0: even if it
  136. // may get bumped by an AddRef by mistake, it will return to 0.
  137. //
  138. LONG RefCount;
  139. //
  140. // This is set when somebody wants to gain exclusive access to the
  141. // protected structure.
  142. //
  143. LONG Exclusive;
  144. } CCPF_REFCOUNT, *PCCPF_REFCOUNT;
  145. //
  146. // Define structures used for logging pagefaults:
  147. //
  148. //
  149. // One of these is logged for every page fault.
  150. //
  151. typedef struct _CCPF_LOG_ENTRY {
  152. //
  153. // File offset of the page that was faulted.
  154. //
  155. ULONG FileOffset;
  156. //
  157. // Index into the section table in the trace header that helps us
  158. // identify the file.
  159. //
  160. USHORT SectionId;
  161. //
  162. // Whether this page was faulted as an image page or data page.
  163. //
  164. BOOLEAN IsImage;
  165. } CCPF_LOG_ENTRY, *PCCPF_LOG_ENTRY;
  166. //
  167. // CCPF_LOG_ENTRIES is a buffer of log entries with a small header containing
  168. // an index to the highest used entry. This is used so that a trace can consist
  169. // of several smaller trace buffers instead of one large, fixed-size buffer.
  170. // The current index must be contained in the buffer in order to allow entries
  171. // to be added without acquiring a spin lock.
  172. //
  173. typedef struct _CCPF_LOG_ENTRIES {
  174. //
  175. // Link used to put this buffer in the traces's buffer list.
  176. //
  177. LIST_ENTRY TraceBuffersLink;
  178. //
  179. // NumEntries is the current number of entries in the buffer. MaxEntries
  180. // is the maximum number of entries that can be placed in the buffer.
  181. // (Currently MaxEntries always equals CCPF_TRACE_BUFFER_MAX_ENTRIES.)
  182. //
  183. LONG NumEntries;
  184. LONG MaxEntries;
  185. //
  186. // The logged entries start here.
  187. //
  188. CCPF_LOG_ENTRY Entries[1];
  189. } CCPF_LOG_ENTRIES, *PCCPF_LOG_ENTRIES;
  190. //
  191. // CCPF_TRACE_BUFFER_SIZE is the size of an allocated CCPF_LOG_ENTRIES structure
  192. // (including the header). This should be a multiple of the page size.
  193. //
  194. #define CCPF_TRACE_BUFFER_SIZE 8192
  195. //
  196. // CCPF_TRACE_BUFFER_MAX_ENTRIES is the number of log entries that will fit in
  197. // a trace buffer of size CCPF_TRACE_BUFFER_SIZE.
  198. //
  199. #define CCPF_TRACE_BUFFER_MAX_ENTRIES (((CCPF_TRACE_BUFFER_SIZE - sizeof(CCPF_LOG_ENTRIES)) / sizeof(CCPF_LOG_ENTRY)) + 1)
  200. //
  201. // This structure associates a SectionObjectPointer with a file name
  202. // in the runtime trace buffer. There is a table of these in the trace
  203. // header and every page fault has an index into this table denoting
  204. // which file it is to.
  205. //
  206. typedef struct DECLSPEC_ALIGN(MEMORY_ALLOCATION_ALIGNMENT) _CCPF_SECTION_INFO {
  207. //
  208. // Section info entries are kept in a hash. This field is
  209. // InterlockedCompareExchange'd to denote that it is in use.
  210. //
  211. LONG EntryValid;
  212. //
  213. // Whether this section is used for file systems to map metafile.
  214. //
  215. ULONG Metafile:1;
  216. ULONG Unused:31;
  217. //
  218. // SectionObjectPointer used as a unique identifier to a file
  219. // mapping. The same file may be mapped using a number of file
  220. // objects, but the SectionObjectPointer fields of all those file
  221. // objects will be the same.
  222. //
  223. PSECTION_OBJECT_POINTERS SectionObjectPointer;
  224. //
  225. // All references to all file objects for a file may be released,
  226. // and a new file may be opened using the same memory block for
  227. // its FCB at which point the SectionObjectPointer would no longer
  228. // be unique. This would result in pagefaults getting logged under
  229. // the entry for the file that was closed. The consequences would
  230. // be misprefetching wrong pages from a couple of sections until
  231. // the scenario corrects itself by looking at new traces. By
  232. // keeping track of these two fields of the SectionObjectPointers
  233. // to check for uniqueness we make this case very unlikely to
  234. // happen. The other solutions we thought of to solve this issue
  235. // 100% were too costly in terms of complication or efficiency.
  236. //
  237. //
  238. // In order to avoid adding two entries to the table for the
  239. // section when it is used as data first then image (or vice
  240. // versa) it is assumed that it is still the same section if the
  241. // current entry's Data/ImageSectionObject is NULL but the
  242. // Data/ImageSectionObject of the section we are logging a new
  243. // pagefault to is not. Then we try to update the NULL pointer
  244. // with the new value using InterlockedCompareExchangePointer.
  245. //
  246. PVOID DataSectionObject;
  247. PVOID ImageSectionObject;
  248. //
  249. // This may point to a file object that we have referenced to
  250. // ensure the section object stays around until we can get a name.
  251. //
  252. PFILE_OBJECT ReferencedFileObject;
  253. //
  254. // The name is set as soon as we can get a file name. We cannot
  255. // access the file name while running at a high IRQL.
  256. //
  257. WCHAR *FileName;
  258. //
  259. // We queue a section to the get-file-name list using this field.
  260. //
  261. SLIST_ENTRY GetNameLink;
  262. } CCPF_SECTION_INFO, *PCCPF_SECTION_INFO;
  263. //
  264. // This structure contains information on a volume on which sections
  265. // in the trace are located on.
  266. //
  267. typedef struct _CCPF_VOLUME_INFO {
  268. //
  269. // Link in the trace's volume list.
  270. //
  271. LIST_ENTRY VolumeLink;
  272. //
  273. // Volume creation time and serial number used to identify the
  274. // volume in case its NT/device path e.g. \Device\HarddiskVolume1
  275. // changes.
  276. //
  277. LARGE_INTEGER CreationTime;
  278. ULONG SerialNumber;
  279. //
  280. // Current NT/device path for the volume and its length in
  281. // characters excluding terminating NUL.
  282. //
  283. ULONG VolumePathLength;
  284. WCHAR VolumePath[1];
  285. } CCPF_VOLUME_INFO, *PCCPF_VOLUME_INFO;
  286. //
  287. // This is the runtime trace header for a scenario.
  288. //
  289. typedef struct _CCPF_TRACE_HEADER {
  290. //
  291. // Magic number identifying this structure as a trace.
  292. //
  293. ULONG Magic;
  294. //
  295. // Link in the active traces list.
  296. //
  297. LIST_ENTRY ActiveTracesLink;
  298. //
  299. // Scenario id for which we are acquiring this trace.
  300. //
  301. PF_SCENARIO_ID ScenarioId;
  302. //
  303. // Type of this scenario.
  304. //
  305. PF_SCENARIO_TYPE ScenarioType;
  306. //
  307. // CurrentTraceBuffer is the active trace buffer.
  308. //
  309. PCCPF_LOG_ENTRIES CurrentTraceBuffer;
  310. //
  311. // This is the list of trace buffers for this trace.
  312. // CurrentTraceBuffer is the last element. Both this list and
  313. // CurrentTraceBuffer are protected by TraceBufferSpinLock.
  314. //
  315. LIST_ENTRY TraceBuffersList;
  316. ULONG NumTraceBuffers;
  317. KSPIN_LOCK TraceBufferSpinLock;
  318. //
  319. // This is the table for section info.
  320. //
  321. PCCPF_SECTION_INFO SectionInfoTable;
  322. LONG NumSections;
  323. LONG MaxSections;
  324. ULONG SectionTableSize;
  325. //
  326. // We don't log timestamps with page faults but it helps to know
  327. // how many we are logging per given time. This information can be
  328. // used to mark the end of a scenario.
  329. //
  330. KTIMER TraceTimer;
  331. LARGE_INTEGER TraceTimerPeriod;
  332. KDPC TraceTimerDpc;
  333. KSPIN_LOCK TraceTimerSpinLock;
  334. //
  335. // This array contains the number of page faults logged per trace
  336. // period.
  337. //
  338. ULONG FaultsPerPeriod[PF_MAX_NUM_TRACE_PERIODS];
  339. LONG LastNumFaults;
  340. LONG CurPeriod;
  341. //
  342. // NumFaults is the number of faults that have been logged so far, in all
  343. // trace buffers. MaxFaults is the maximum number of page faults we will
  344. // log, in all trace buffers.
  345. //
  346. LONG NumFaults;
  347. LONG MaxFaults;
  348. //
  349. // This workitem is queued to get names for file objects we are
  350. // logging page faults to. First GetFileNameWorkItemQueued should
  351. // be InterlockedCompareExchange'd from 0 to 1 and a reference
  352. // should be acquired on the scenario. The workitem will free this
  353. // reference just before it completes.
  354. //
  355. WORK_QUEUE_ITEM GetFileNameWorkItem;
  356. LONG GetFileNameWorkItemQueued;
  357. //
  358. // Sections for which we have to get names are pushed and popped
  359. // to/from this slist.
  360. //
  361. SLIST_HEADER SectionsWithoutNamesList;
  362. //
  363. // Because we don't want to incur the cost of queuing a work item
  364. // to get file names for every one or two sections, the worker we
  365. // queue will wait on this event before returning. The event can
  366. // be signaled when a new section comes, or when the scenario is
  367. // ending.
  368. //
  369. KEVENT GetFileNameWorkerEvent;
  370. //
  371. // This is the process we are associated with.
  372. //
  373. PEPROCESS Process;
  374. //
  375. // This is the removal reference count protecting us.
  376. //
  377. CCPF_REFCOUNT RefCount;
  378. //
  379. // This work item can be queued to call the end trace function if
  380. // the trace times out or we log to many entries etc. First
  381. // EndTraceCalled should be InterlockedCompareExchange'd from 0 to
  382. // 1.
  383. //
  384. WORK_QUEUE_ITEM EndTraceWorkItem;
  385. //
  386. // Before anybody calls end trace function, they have to
  387. // InterlockedCompareExchange this from 0 to 1 to ensure this
  388. // function gets called only once.
  389. //
  390. LONG EndTraceCalled;
  391. //
  392. // This is the list of volumes the sections we are tracing are
  393. // located on. It is sorted lexically by the volume NT/device path.
  394. //
  395. LIST_ENTRY VolumeList;
  396. ULONG NumVolumes;
  397. //
  398. // This is the pointer to the built trace dump from this runtime
  399. // trace structure and the status with which dumping failed if it
  400. // did. These are useful for debugging on retail builds.
  401. //
  402. struct _CCPF_TRACE_DUMP *TraceDump;
  403. NTSTATUS TraceDumpStatus;
  404. //
  405. // System time when we started tracing.
  406. //
  407. LARGE_INTEGER LaunchTime;
  408. } CCPF_TRACE_HEADER, *PCCPF_TRACE_HEADER;
  409. //
  410. // This structure is used to save completed traces in a list. The
  411. // trace extends beyond this structure as necessary.
  412. //
  413. typedef struct _CCPF_TRACE_DUMP {
  414. //
  415. // Link in the completed traces list.
  416. //
  417. LIST_ENTRY CompletedTracesLink;
  418. //
  419. // Completed trace.
  420. //
  421. PF_TRACE_HEADER Trace;
  422. } CCPF_TRACE_DUMP, *PCCPF_TRACE_DUMP;
  423. //
  424. // This structure contains information for a volume used during prefetching.
  425. //
  426. typedef struct _CCPF_PREFETCH_VOLUME_INFO {
  427. //
  428. // Link in the lists this volume gets put on.
  429. //
  430. LIST_ENTRY VolumeLink;
  431. //
  432. // Volume path.
  433. //
  434. WCHAR *VolumePath;
  435. ULONG VolumePathLength;
  436. //
  437. // Handle to the opened volume.
  438. //
  439. HANDLE VolumeHandle;
  440. } CCPF_PREFETCH_VOLUME_INFO, *PCCPF_PREFETCH_VOLUME_INFO;
  441. //
  442. // This structure is used to keep track of prefetched pages & context.
  443. //
  444. //
  445. // Note: This structure is used as a stack variable. Don't add events
  446. // etc, without changing that.
  447. //
  448. typedef struct _CCPF_PREFETCH_HEADER {
  449. //
  450. // Pointer to prefetch instructions. The instructions should not
  451. // be removed / freed until the prefetch header is cleaned up.
  452. // E.g. VolumeNodes may point to volume paths in the scenario.
  453. //
  454. PPF_SCENARIO_HEADER Scenario;
  455. //
  456. // Nodes for the volumes we are going to prefetch from.
  457. //
  458. PCCPF_PREFETCH_VOLUME_INFO VolumeNodes;
  459. //
  460. // List of volumes we won't prefetch on.
  461. //
  462. LIST_ENTRY BadVolumeList;
  463. //
  464. // List of volumes we have opened. They are opened with the following
  465. // flags: FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES | SYNCHRONIZE
  466. //
  467. LIST_ENTRY OpenedVolumeList;
  468. } CCPF_PREFETCH_HEADER, *PCCPF_PREFETCH_HEADER;
  469. //
  470. // Define types of prefetching CcPfPrefetchSections can be called to
  471. // perform.
  472. //
  473. typedef enum _CCPF_PREFETCH_TYPE {
  474. CcPfPrefetchAllDataPages,
  475. CcPfPrefetchAllImagePages,
  476. CcPfPrefetchPartOfDataPages,
  477. CcPfPrefetchPartOfImagePages,
  478. CcPfMaxPrefetchType
  479. } CCPF_PREFETCH_TYPE, *PCCPF_PREFETCH_TYPE;
  480. //
  481. // This structure stands for the position in the prefetch
  482. // instructions. It is used and updated by CcPfPrefetchSections when
  483. // prefetching parts of a scenario at a time.
  484. //
  485. typedef struct _CCPF_PREFETCH_CURSOR {
  486. //
  487. // Index of the current section and the page in that section.
  488. //
  489. ULONG SectionIdx;
  490. ULONG PageIdx;
  491. } CCPF_PREFETCH_CURSOR, *PCCPF_PREFETCH_CURSOR;
  492. //
  493. // This type is used in CcPfPrefetchSections.
  494. //
  495. typedef struct _SECTION *PSECTION;
  496. //
  497. // Define types of information CcPfQueryScenarioInformation can be
  498. // asked to return.
  499. //
  500. typedef enum _CCPF_SCENARIO_INFORMATION_TYPE {
  501. CcPfBasicScenarioInformation,
  502. CcPfBootScenarioInformation,
  503. CcPfMaxScenarioInformationType
  504. } CCPF_SCENARIO_INFORMATION_TYPE, *PCCPF_SCENARIO_INFORMATION_TYPE;
  505. //
  506. // This structure contains basic scenario information.
  507. //
  508. typedef struct _CCPF_BASIC_SCENARIO_INFORMATION {
  509. //
  510. // Number of pages that will be prefetched as data pages.
  511. //
  512. ULONG NumDataPages;
  513. //
  514. // Number of pages that will be prefetched as image pages.
  515. //
  516. ULONG NumImagePages;
  517. //
  518. // Number of sections for which only data pages will be
  519. // prefetched.
  520. //
  521. ULONG NumDataOnlySections;
  522. //
  523. // Number of sections for which only image pages will be
  524. // prefetched excluding the header page.
  525. //
  526. ULONG NumImageOnlySections;
  527. //
  528. // Number of ignored pages.
  529. //
  530. ULONG NumIgnoredPages;
  531. //
  532. // Number of ignored sections.
  533. //
  534. ULONG NumIgnoredSections;
  535. } CCPF_BASIC_SCENARIO_INFORMATION, *PCCPF_BASIC_SCENARIO_INFORMATION;
  536. //
  537. // Routines used in the core prefetcher.
  538. //
  539. //
  540. // Routines used in prefetch tracing.
  541. //
  542. NTSTATUS
  543. CcPfBeginTrace(
  544. IN PF_SCENARIO_ID *ScenarioId,
  545. IN PF_SCENARIO_TYPE ScenarioType,
  546. IN PEPROCESS Process
  547. );
  548. NTSTATUS
  549. CcPfActivateTrace(
  550. IN PCCPF_TRACE_HEADER Scenario
  551. );
  552. NTSTATUS
  553. CcPfDeactivateTrace(
  554. IN PCCPF_TRACE_HEADER Scenario
  555. );
  556. NTSTATUS
  557. CcPfEndTrace(
  558. IN PCCPF_TRACE_HEADER Trace
  559. );
  560. NTSTATUS
  561. CcPfBuildDumpFromTrace(
  562. OUT PCCPF_TRACE_DUMP *TraceDump,
  563. IN PCCPF_TRACE_HEADER RuntimeTrace
  564. );
  565. VOID
  566. CcPfCleanupTrace(
  567. IN PCCPF_TRACE_HEADER Trace
  568. );
  569. VOID
  570. CcPfTraceTimerRoutine(
  571. IN PKDPC Dpc,
  572. IN PVOID DeferredContext,
  573. IN PVOID SystemArgument1,
  574. IN PVOID SystemArgument2
  575. );
  576. NTSTATUS
  577. CcPfCancelTraceTimer(
  578. IN PCCPF_TRACE_HEADER Trace
  579. );
  580. VOID
  581. CcPfEndTraceWorkerThreadRoutine(
  582. PVOID Parameter
  583. );
  584. VOID
  585. CcPfGetFileNamesWorkerRoutine(
  586. PVOID Parameter
  587. );
  588. LONG
  589. CcPfLookUpSection(
  590. PCCPF_SECTION_INFO Table,
  591. ULONG TableSize,
  592. PSECTION_OBJECT_POINTERS SectionObjectPointer,
  593. PLONG AvailablePosition
  594. );
  595. NTSTATUS
  596. CcPfGetCompletedTrace (
  597. PVOID Buffer,
  598. ULONG BufferSize,
  599. PULONG ReturnSize
  600. );
  601. NTSTATUS
  602. CcPfUpdateVolumeList(
  603. PCCPF_TRACE_HEADER Trace,
  604. WCHAR *VolumePath,
  605. ULONG VolumePathLength
  606. );
  607. //
  608. // Routines used for prefetching and dealing with prefetch instructions.
  609. //
  610. NTSTATUS
  611. CcPfPrefetchScenario (
  612. PPF_SCENARIO_HEADER Scenario
  613. );
  614. NTSTATUS
  615. CcPfPrefetchSections(
  616. IN PCCPF_PREFETCH_HEADER PrefetchHeader,
  617. IN CCPF_PREFETCH_TYPE PrefetchType,
  618. OPTIONAL IN PCCPF_PREFETCH_CURSOR StartCursor,
  619. OPTIONAL PFN_NUMBER TotalPagesToPrefetch,
  620. OPTIONAL OUT PPFN_NUMBER NumPagesPrefetched,
  621. OPTIONAL OUT PCCPF_PREFETCH_CURSOR EndCursor
  622. );
  623. NTSTATUS
  624. CcPfPrefetchMetadata(
  625. IN PCCPF_PREFETCH_HEADER PrefetchHeader
  626. );
  627. NTSTATUS
  628. CcPfPrefetchDirectoryContents(
  629. WCHAR *DirectoryPath,
  630. WCHAR DirectoryPathlength
  631. );
  632. NTSTATUS
  633. CcPfPrefetchFileMetadata(
  634. HANDLE VolumeHandle,
  635. PFILE_PREFETCH FilePrefetch
  636. );
  637. VOID
  638. CcPfInitializePrefetchHeader (
  639. OUT PCCPF_PREFETCH_HEADER PrefetchHeader
  640. );
  641. VOID
  642. CcPfCleanupPrefetchHeader (
  643. IN PCCPF_PREFETCH_HEADER PrefetchHeader
  644. );
  645. NTSTATUS
  646. CcPfGetPrefetchInstructions(
  647. IN PPF_SCENARIO_ID ScenarioId,
  648. IN PF_SCENARIO_TYPE ScenarioType,
  649. OUT PPF_SCENARIO_HEADER *ScenarioHeader
  650. );
  651. NTSTATUS
  652. CcPfQueryScenarioInformation(
  653. IN PPF_SCENARIO_HEADER Scenario,
  654. IN CCPF_SCENARIO_INFORMATION_TYPE InformationType,
  655. OUT PVOID Buffer,
  656. IN ULONG BufferSize,
  657. OUT PULONG RequiredSize
  658. );
  659. NTSTATUS
  660. CcPfOpenVolumesForPrefetch (
  661. IN PCCPF_PREFETCH_HEADER PrefetchHeader
  662. );
  663. PCCPF_PREFETCH_VOLUME_INFO
  664. CcPfFindPrefetchVolumeInfoInList(
  665. WCHAR *Path,
  666. PLIST_ENTRY List
  667. );
  668. NTSTATUS
  669. CcPfGetSectionObject(
  670. IN PUNICODE_STRING FileName,
  671. IN LOGICAL ImageSection,
  672. OUT PVOID* SectionObject,
  673. OUT PFILE_OBJECT* FileObject,
  674. OUT HANDLE* FileHandle
  675. );
  676. //
  677. // Routines used for application launch prefetching.
  678. //
  679. BOOLEAN
  680. CcPfIsHostingApplication(
  681. IN PWCHAR ExecutableName
  682. );
  683. NTSTATUS
  684. CcPfScanCommandLine(
  685. OUT PULONG PrefetchHint,
  686. OPTIONAL OUT PULONG HashId
  687. );
  688. //
  689. // Reference count functions:
  690. //
  691. VOID
  692. CcPfInitializeRefCount(
  693. PCCPF_REFCOUNT RefCount
  694. );
  695. NTSTATUS
  696. FASTCALL
  697. CcPfAddRef(
  698. PCCPF_REFCOUNT RefCount
  699. );
  700. VOID
  701. FASTCALL
  702. CcPfDecRef(
  703. PCCPF_REFCOUNT RefCount
  704. );
  705. NTSTATUS
  706. FASTCALL
  707. CcPfAddRefEx(
  708. PCCPF_REFCOUNT RefCount,
  709. ULONG Count
  710. );
  711. VOID
  712. FASTCALL
  713. CcPfDecRefEx(
  714. PCCPF_REFCOUNT RefCount,
  715. ULONG Count
  716. );
  717. NTSTATUS
  718. CcPfAcquireExclusiveRef(
  719. PCCPF_REFCOUNT RefCount
  720. );
  721. PCCPF_TRACE_HEADER
  722. CcPfReferenceProcessTrace(
  723. PEPROCESS Process
  724. );
  725. PCCPF_TRACE_HEADER
  726. CcPfRemoveProcessTrace(
  727. PEPROCESS Process
  728. );
  729. NTSTATUS
  730. CcPfAddProcessTrace(
  731. PEPROCESS Process,
  732. PCCPF_TRACE_HEADER Trace
  733. );
  734. //
  735. // Utility routines.
  736. //
  737. PWCHAR
  738. CcPfFindString (
  739. PUNICODE_STRING SearchIn,
  740. PUNICODE_STRING SearchFor
  741. );
  742. ULONG
  743. CcPfHashValue(
  744. PVOID Key,
  745. ULONG Len
  746. );
  747. NTSTATUS
  748. CcPfIsVolumeMounted (
  749. IN WCHAR *VolumePath,
  750. OUT BOOLEAN *VolumeMounted
  751. );
  752. NTSTATUS
  753. CcPfQueryVolumeInfo (
  754. IN WCHAR *VolumePath,
  755. OPTIONAL OUT HANDLE *VolumeHandleOut,
  756. OUT PLARGE_INTEGER CreationTime,
  757. OUT PULONG SerialNumber
  758. );
  759. //
  760. // Declarations and definitions for prefetcher parameters.
  761. //
  762. //
  763. // Define location of registry key for prefetch parameters.
  764. //
  765. #define CCPF_PARAMETERS_KEY L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Session Manager\\Memory Management\\PrefetchParameters"
  766. //
  767. // Maximum characters in registry value names for prefetch parameters.
  768. //
  769. #define CCPF_MAX_PARAMETER_NAME_LENGTH 80
  770. //
  771. // Maximum bytes needed to query a prefetch parameter from the
  772. // registry. Currently our largest parameter would be the hosting
  773. // application list.
  774. //
  775. #define CCPF_MAX_PARAMETER_VALUE_BUFFER ((PF_HOSTING_APP_LIST_MAX_CHARS * sizeof(WCHAR)) + sizeof(KEY_VALUE_PARTIAL_INFORMATION))
  776. NTSTATUS
  777. CcPfParametersInitialize (
  778. PCCPF_PREFETCHER_PARAMETERS PrefetcherParameters
  779. );
  780. VOID
  781. CcPfParametersSetDefaults (
  782. PCCPF_PREFETCHER_PARAMETERS PrefetcherParameters
  783. );
  784. NTSTATUS
  785. CcPfParametersRead (
  786. PCCPF_PREFETCHER_PARAMETERS PrefetcherParameters
  787. );
  788. NTSTATUS
  789. CcPfParametersSave (
  790. PCCPF_PREFETCHER_PARAMETERS PrefetcherParameters
  791. );
  792. NTSTATUS
  793. CcPfParametersVerify (
  794. PPF_SYSTEM_PREFETCH_PARAMETERS Parameters
  795. );
  796. VOID
  797. CcPfParametersWatcher (
  798. IN PVOID Context
  799. );
  800. NTSTATUS
  801. CcPfParametersSetChangedEvent (
  802. PCCPF_PREFETCHER_PARAMETERS PrefetcherParameters
  803. );
  804. NTSTATUS
  805. CcPfGetParameter (
  806. HANDLE ParametersKey,
  807. WCHAR *ValueNameBuffer,
  808. ULONG ValueType,
  809. PVOID Value,
  810. ULONG *ValueSize
  811. );
  812. NTSTATUS
  813. CcPfSetParameter (
  814. HANDLE ParametersKey,
  815. WCHAR *ValueNameBuffer,
  816. ULONG ValueType,
  817. PVOID Value,
  818. ULONG ValueSize
  819. );
  820. LOGICAL
  821. CcPfDetermineEnablePrefetcher(
  822. VOID
  823. );
  824. //
  825. // Declarations and definitions for boot prefetching.
  826. //
  827. //
  828. // Value name under prefetcher parameters key where we store how long
  829. // video initialization took during boot.
  830. //
  831. #define CCPF_VIDEO_INIT_TIME_VALUE_NAME L"VideoInitTime"
  832. //
  833. // How long (in milliseconds) video initialization could take max. This value
  834. // is used to sanity check the value read from the registry.
  835. //
  836. #define CCPF_MAX_VIDEO_INIT_TIME (10 * 1000) // 10 seconds
  837. //
  838. // Value name under prefetcher parameters key where we store how many
  839. // pages we should try to prefetch per second of video initialization.
  840. //
  841. #define CCPF_VIDEO_INIT_PAGES_PER_SECOND_VALUE_NAME L"VideoInitPagesPerSecond"
  842. //
  843. // Sanity check maximum value for video init pages per second.
  844. //
  845. #define CCPF_VIDEO_INIT_MAX_PAGES_PER_SECOND 128000
  846. //
  847. // How many pages will we try to prefetch in parallel to video initialization
  848. // per second of it.
  849. //
  850. #define CCPF_VIDEO_INIT_DEFAULT_PAGES_PER_SECOND 1500
  851. //
  852. // Maximum number of chunks in which we will prefetch for boot.
  853. //
  854. #define CCPF_MAX_BOOT_PREFETCH_PHASES 16
  855. //
  856. // Different phases of boot we return page counts for in
  857. // CCPF_BOOT_SCENARIO_INFORMATION.
  858. //
  859. typedef enum _CCPF_BOOT_SCENARIO_PHASE {
  860. CcPfBootScenDriverInitPhase,
  861. CcPfBootScenSubsystemInitPhase,
  862. CcPfBootScenSystemProcInitPhase,
  863. CcPfBootScenServicesInitPhase,
  864. CcPfBootScenUserInitPhase,
  865. CcPfBootScenMaxPhase
  866. } CCPF_BOOT_SCENARIO_PHASE, *PCCPF_BOOT_SCENARIO_PHASE;
  867. //
  868. // Define structure to hold boot prefetching state.
  869. //
  870. typedef struct _CCPF_BOOT_PREFETCHER {
  871. //
  872. // These events are signaled by the boot prefetch worker when
  873. // it has completed prefetching for the specified phase.
  874. //
  875. KEVENT SystemDriversPrefetchingDone;
  876. KEVENT PreSmssPrefetchingDone;
  877. KEVENT VideoInitPrefetchingDone;
  878. //
  879. // This event will be signaled when we start initializing video
  880. // on the console. Boot prefetcher waits on this event to perform
  881. // prefetching parallel to video initialization.
  882. //
  883. KEVENT VideoInitStarted;
  884. } CCPF_BOOT_PREFETCHER, *PCCPF_BOOT_PREFETCHER;
  885. //
  886. // This structure contains boot scenario information.
  887. //
  888. typedef struct _CCPF_BOOT_SCENARIO_INFORMATION {
  889. //
  890. // These are the number of data/image pages to prefetch for the
  891. // different phase of boot.
  892. //
  893. ULONG NumDataPages[CcPfBootScenMaxPhase];
  894. ULONG NumImagePages[CcPfBootScenMaxPhase];
  895. } CCPF_BOOT_SCENARIO_INFORMATION, *PCCPF_BOOT_SCENARIO_INFORMATION;
  896. //
  897. // We will be prefetching data and image pages for boot in parts. Since the
  898. // code is mostly same to prefetch the data and image pages, we keep track
  899. // of where we left off and what to prefetch next in a common boot prefetch
  900. // cursor structure and make two passes (first for data, then for image).
  901. //
  902. typedef struct _CCPF_BOOT_PREFETCH_CURSOR {
  903. //
  904. // Start & end cursors passed to prefetch sections function.
  905. //
  906. CCPF_PREFETCH_CURSOR StartCursor;
  907. CCPF_PREFETCH_CURSOR EndCursor;
  908. //
  909. // How to prefetch (e.g. part of data pages or part of image pages).
  910. //
  911. CCPF_PREFETCH_TYPE PrefetchType;
  912. //
  913. // How many pages to prefetch per phase.
  914. //
  915. ULONG NumPagesForPhase[CCPF_MAX_BOOT_PREFETCH_PHASES];
  916. } CCPF_BOOT_PREFETCH_CURSOR, *PCCPF_BOOT_PREFETCH_CURSOR;
  917. //
  918. // Boot prefetching routines.
  919. //
  920. VOID
  921. CcPfBootWorker(
  922. PCCPF_BOOT_PREFETCHER BootPrefetcher
  923. );
  924. NTSTATUS
  925. CcPfBootQueueEndTraceTimer (
  926. PLARGE_INTEGER Timeout
  927. );
  928. VOID
  929. CcPfEndBootTimerRoutine(
  930. IN PKDPC Dpc,
  931. IN PVOID DeferredContext,
  932. IN PVOID SystemArgument1,
  933. IN PVOID SystemArgument2
  934. );
  935. //
  936. // Debug routines.
  937. //
  938. #if CCPF_DBG
  939. NTSTATUS
  940. CcPfWriteToFile(
  941. IN PVOID pData,
  942. IN ULONG Size,
  943. IN WCHAR *pFileName
  944. );
  945. #endif // CCPF_DBG
  946. //
  947. // Define useful macros. As with all macros, must be careful of
  948. // parameter reevalation. Don't use expressions as macro parameters.
  949. //
  950. #define CCPF_MAX(A,B) (((A) >= (B)) ? (A) : (B))
  951. #define CCPF_MIN(A,B) (((A) <= (B)) ? (A) : (B))
  952. //
  953. // Define debugging macros:
  954. //
  955. //
  956. // Define the component ID we use.
  957. //
  958. #define CCPFID DPFLTR_PREFETCHER_ID
  959. //
  960. // Define DbgPrintEx levels.
  961. //
  962. #define PFERR DPFLTR_ERROR_LEVEL
  963. #define PFWARN DPFLTR_WARNING_LEVEL
  964. #define PFTRC DPFLTR_TRACE_LEVEL
  965. #define PFINFO DPFLTR_INFO_LEVEL
  966. #define PFPREF 4
  967. #define PFPRFD 5
  968. #define PFPRFF 6
  969. #define PFPRFZ 7
  970. #define PFTRAC 8
  971. #define PFTMR 9
  972. #define PFNAME 10
  973. #define PFNAMS 11
  974. #define PFLKUP 12
  975. #define PFBOOT 13
  976. //
  977. // DbgPrintEx levels 20 - 31 are reserved for the service.
  978. //
  979. //
  980. // This may help you determine what to set the DbgPrintEx mask.
  981. //
  982. // 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0
  983. // 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
  984. // _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
  985. //
  986. //
  987. // CCPF_DBG can be defined if you want to turn on asserts and debug
  988. // prints in prefetcher code but you do not want to have a checked
  989. // kernel. Defining CCPF_DBG overrides defining DBG.
  990. //
  991. #if CCPF_DBG
  992. NTSYSAPI
  993. VOID
  994. NTAPI
  995. RtlAssert(
  996. PVOID FailedAssertion,
  997. PVOID FileName,
  998. ULONG LineNumber,
  999. PCHAR Message
  1000. );
  1001. #define DBGPR(x) DbgPrintEx x
  1002. #define CCPF_ASSERT(x) if (!(x)) RtlAssert(#x, __FILE__, __LINE__, NULL )
  1003. #else // CCPF_DBG
  1004. //
  1005. // If CCPF_DBG is not defined, build with debug prints and asserts
  1006. // only on checked build.
  1007. //
  1008. #if DBG
  1009. #define DBGPR(x) DbgPrintEx x
  1010. #define CCPF_ASSERT(x) ASSERT(x)
  1011. #else // DBG
  1012. //
  1013. // On a free build we don't compile with debug prints or asserts.
  1014. //
  1015. #define DBGPR(x)
  1016. #define CCPF_ASSERT(x)
  1017. #endif // DBG
  1018. #endif // CCPF_DBG
  1019. #endif // _PREFTCHP_H