Once I sat down to troubleshoot, I noticed a number of things. First of all, the system was indeed misbehaving and often took several seconds to respond to mouse clicks. In addition, my mom was still running a copy of Windows 10 1511, which - as of a few weeks ago - is out of support. Knowing, that the latter issue couldn't be the cause of the slow system performance, I put it on the backburner and turned to my favorite troubleshooting tools for help.
I knew from my experience that very often this kind of issues are caused by the resource shortage. Wondering if perhaps a process was hogging the CPU or the SSD, I opened Process Explorer. Unfortunately, the system load was nominal, dashing my hopes for quickly finding a clue.
Next, I remembered what Mark Russinovich keeps saying during his TechEd / Ignite sessions: "When in doubt, run Process Monitor", so I ran Process Monitor and captured a 3-minute trace. What I love about Process Monitor is that it allows you to use different troubleshooting approaches to gain insights into what is going on on your system.
On a hunch, I opened the "Process Activity Summary" window, hoping that it might offer some insight:
Process Monitory "Process Activity Summary" allows to sort processes - among other things - by file or registry.
While the file activity summary was unenlightening, showing some generic processes with a light load at the top, the registry activity summary was much more interesting. It showed a RunDll32.exe process causing high load on the registry. RunDll32 is a utility which allows to load and run dynamic-link libraries (DLLs), in this case, HPStatusBL.dll, part of the HP Officejet Pro 8610 printer driver, which monitors ink levels and displays a low ink warning if applicable.
I was fairly certain that I located the culprit, so I turned my attention back to the trace output and configured a filter that excluded everything but the RunDll32.exe process. As I scanned quickly to get an overall view, I noticed the following pattern:
The process was repeatedly querying (polling) a non-existing registry key HKCU\Software\HP\NG\Logging. In the application, context polling is undesirable because it is causing performance degradation and excessive use of resources. As Mark Russinovich explained in a blog post a couple of years ago, "when the thread wakes up and the kernel schedules it, the system must context-switch away from potentially useful work to the polling thread." When execution switches from one process to another, this event causes the invalidation of the Translation Lookaside Buffer (TLB), a small associative memory that caches virtual to physical page table address on processor thus leading to increase in speed of virtual memory operations through the inherent latency-reducing proximity. Because each process has its own address space, the entire TLB becomes invalid on a context switch and it is up to the operating system to ensure that invalid (stale) entries are flushed from the TLB before they can cause any harm. Flushing TLB is a really expensive affair and should be avoided - it is, however, common to poorly written software.
Assuming that there might be an updated driver version available, which might address this issue, I checked the HP website just to be sure and it turned out there was no newer driver package available.
From past experience, I knew that the HKCU\Software\HP\NG\Logging registry key is usually used to configure HP WS Pro Proxy Agent logging. Adding the missing registry key and corresponding values did not help. All it did was generating a log file with cryptic entries. However, neither did this reduce the number of registry queries nor did it improve system's performance.
As I was quickly running of ideas, I decided to disable the trigger which launched the HP status bar. On a hunch, I decided to launch Sysinternals Autoruns because I suspected that HP configured a Run key to load the HPStatusBL.dll upon user logon. I located and disabled the RunDll32 entry. In order to confirm my fix (workaround to be precise) I logged off and logged back on with fingers crossed and to my immense satisfaction performance issues were gone thus confirming my suspicions that registry polling was to blame. The case was closed! As to why HPStatusBL.dll was polling the registry key - while I might have been able to gain a deeper understanding of the underlying functionality if I would have attached a debugger to the process - I did not have the time to investigate further. Is anyone from HP reading this?
As the main case was closed, there was still the issue of applying Creators Update to the outdated Windows 10 1511 installation. Each Windows 10 update requires 20 GB of free space, so I spent some time moving files from the OS to data partition, ran Windows Update and after 40 minutes my mom's system was usable again. The coup de grâce was setting default mailing application to Outlook 2016. The critical support incident was closed!