Skip to content
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

Improve flushing pagecache on darwin #1883

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
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: 0 additions & 1 deletion configure
Original file line number Diff line number Diff line change
Expand Up @@ -2997,7 +2997,6 @@ fi
print_config "timerfd_create" "$timerfd_create"

#############################################################################

if test "$wordsize" = "64" ; then
output_sym "CONFIG_64BIT"
elif test "$wordsize" = "32" ; then
Expand Down
10 changes: 10 additions & 0 deletions helpers.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,19 @@ int sync_file_range(int fd, uint64_t offset, uint64_t nbytes,
}
#endif

#if defined (__APPLE__)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You might be able to move this into os/os-mac.h by doing #define CONFIG_POSIX_FADVISE over there and providing an implementation in that file...

int posix_fadvise(int fd, off_t offset, off_t len, int advice)
{
if (advice == POSIX_FADV_DONTNEED)
return discard_pages(fd, offset, len);
errno = EINVAL;
return -1;
}
#else
#ifndef CONFIG_POSIX_FADVISE
int posix_fadvise(int fd, off_t offset, off_t len, int advice)
{
return 0;
}
#endif
#endif /* defined (__APPLE__) */
62 changes: 62 additions & 0 deletions os/os-mac.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@
#include <machine/endian.h>
#include <libkern/OSByteOrder.h>

#include <sys/stat.h>
#include <sys/mman.h>
#include <stdio.h>


#include "../arch/arch.h"
#include "../file.h"

Expand Down Expand Up @@ -117,3 +122,60 @@ static inline bool os_cpu_has(cpu_features feature)
}

#endif

#if defined (__APPLE__)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You won't need this guard here as os-mac.h will only be included on macOS (see

fio/os/os.h

Line 49 in 58818df

#elif defined(__APPLE__)
).

/*
* discard_pages should not be run within Rosetta. Native arm64 or x86 only.
*/

#define MMAP_CHUNK_SIZE (1024 * 1024 * 1024)

static inline int discard_pages(int fd, off_t offset, off_t size)
{
caddr_t *addr;
uint64_t chunk_size = MMAP_CHUNK_SIZE;

if (fsync(fd) < 0) {
int __err = errno;
fprintf(stderr, "Cannot fsync file\n");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we would be better off using log_err(). Doing a quick grep there isn't a clear standard for how log_err's string should start but perhaps a prefix of "discard_pages: " would make it clear where the error bubbled up from?

errno = __err;
return -1;
}

/*
* mmap the file in 1GB chunks and msync(MS_INVALIDATE).
*/
while (size > 0) {
uint64_t mmap_size = MIN(chunk_size, size);

addr = mmap((caddr_t)0, mmap_size, PROT_NONE, MAP_SHARED, fd, offset);
if (addr == MAP_FAILED) {
int __map_errno = errno;
fprintf(stderr, "Failed to mmap (%s), offset = %llu, size = %llu\n",
strerror(errno), offset, mmap_size);
errno = __map_errno;
return -1;
}

if (msync(addr, mmap_size, MS_INVALIDATE)) {
int __msync_errno = errno;
fprintf(stderr, "msync failed to free cache pages.\n");
errno = __msync_errno;
return -1;
}

/* Destroy the above mappings used to invalidate cache - cleaning up */
if (munmap(addr, mmap_size) < 0) {
int __munmap_errno = errno;
fprintf(stderr, "munmap failed, error = %d.\n", errno);
errno = __munmap_errno;
return -1;
}

size -= mmap_size;
offset += mmap_size;
}

return 0;
}
#endif /* defined (__APPLE__) */
Loading