Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions libmemory-patches/libmemory-patches.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ struct current_memory_info

LIBMEMORY_PATCHES_API extern struct current_memory_info get_current_memory_info(void);
LIBMEMORY_PATCHES_API int overcommit_prevention_enabled(void);
LIBMEMORY_PATCHES_API int overcommit_prevention_exempt(void);
LIBMEMORY_PATCHES_API BOOL memory_available_for_commit(size_t size);
LIBMEMORY_PATCHES_API void touch_committed_pages(void* base, size_t size, uint32_t protect);
LIBMEMORY_PATCHES_API BOOL has_write_flags(uint32_t protect);
Expand Down
92 changes: 92 additions & 0 deletions libmemory-patches/overcommit.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,90 @@ static const uint32_t page_writecopy_flags =
PAGE_WRITECOPY;


/***********************************************************************
* overcommit_prevention_exempt
*
* Determines if this process is exempt from overcommit prevention, but
* should still have it's writable memory mapped pages touched to ensure
* accurate memory tracking.
*/
int overcommit_prevention_exempt(void)
{
static int overcommit_exempt = -1;

if (overcommit_exempt == -1)
{
int exempt_debug;
{
const char *debug_env_var = getenv( "WINE_PREVENT_OVERCOMMIT_EXEMPT_DEBUG" );
exempt_debug = debug_env_var && atoi(debug_env_var);
}

const char *env_var = getenv( "WINE_PREVENT_OVERCOMMIT_EXEMPT" );
if (env_var)
{
FILE *fp;
if (fp = fopen("/proc/self/cmdline", "r"))
{
char argument[1024];
char buffer[1024];
size_t arg_offset = 0;
if (exempt_debug)
{
puts("/proc/self/cmdline tolower:");
}
size_t read;
do
{
read = fread(buffer, 1, sizeof buffer, fp);
for (size_t i = 0; i < read; i++)
{
if (arg_offset < (sizeof argument) - 1)
{
argument[arg_offset++] = tolower(buffer[i]);
}
else
{
argument[(sizeof argument) - 1] = '\0';
}

if (buffer[i] == '\0')
{
int non_empty_argument = arg_offset > 1;
arg_offset = 0;

if (non_empty_argument && exempt_debug)
{
puts(argument);
}

if (non_empty_argument && strstr(argument, env_var))
{
if (exempt_debug)
{
printf(
"detected process name from WINE_PREVENT_OVERCOMMIT_EXEMPT '%s' is present in cmdline tolower argument '%s'. overcommit prevention will be turned off for this specific process.\n",
env_var,
argument);
}
overcommit_exempt = 1;
}
}
}
} while (read > 0);
fclose(fp);
}
}

if (overcommit_exempt == -1)
{
overcommit_exempt = 0;
}
}

return overcommit_exempt;
}

/***********************************************************************
* overcommit_prevention_enabled
*
Expand All @@ -48,6 +132,14 @@ int overcommit_prevention_enabled(void)
{
static int prevent_overcommit = -1;

if (prevent_overcommit == -1)
{
if (overcommit_prevention_exempt())
{
prevent_overcommit = 0;
}
}

if (prevent_overcommit == -1)
{
const char *env_var = getenv( "WINE_PREVENT_OVERCOMMIT" );
Expand Down
6 changes: 3 additions & 3 deletions patches/wine-overcommit-prevention-support.patch
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ index abe1b4dc4ec424c0864d18e726537e680d2ab883..e55d7e68d1b8d3967316f1101cb0ce9b
VIRTUAL_DEBUG_DUMP_VIEW( view );
+
+ /* if overcommit prevention is enabled and we performed a commit, then touch the commited pages */
+ if (write_consumes_memory && overcommit_prevention_enabled()) {
+ if (write_consumes_memory && (overcommit_prevention_enabled() || overcommit_prevention_exempt())) {
+ touch_committed_pages(view->base, size, protect);
+ }
}
Expand All @@ -267,7 +267,7 @@ index abe1b4dc4ec424c0864d18e726537e680d2ab883..e55d7e68d1b8d3967316f1101cb0ce9b
*size_ptr = size;
+
+ /* if overcommit prevention is enabled and we performed a commit, then touch the commited pages */
+ if ((type & MEM_COMMIT) && overcommit_prevention_enabled()) {
+ if ((type & MEM_COMMIT) && (overcommit_prevention_enabled() || overcommit_prevention_exempt())) {
+ touch_committed_pages(base, size, protect);
+ }
}
Expand Down Expand Up @@ -295,7 +295,7 @@ index abe1b4dc4ec424c0864d18e726537e680d2ab883..e55d7e68d1b8d3967316f1101cb0ce9b
status = set_protection( view, base, size, new_prot );
+
+ /* if overcommit prevention is enabled and write access was granted then touch the pages */
+ if (overcommit_prevention_enabled() && write_or_copy_added) {
+ if ((overcommit_prevention_enabled() || overcommit_prevention_exempt()) && write_or_copy_added) {
+ touch_committed_pages(base, size, new_prot);
+ }
}
Expand Down