diff --git a/composite/compalloc.c b/composite/compalloc.c index d16f318c4d..4a19ebd67f 100644 --- a/composite/compalloc.c +++ b/composite/compalloc.c @@ -44,6 +44,9 @@ #include #include +#ifdef HAVE_NUMA +#include +#endif #include "dix/resource_priv.h" #include "os/bug_priv.h" @@ -146,6 +149,7 @@ compRedirectWindow(ClientPtr pClient, WindowPtr pWin, int update) WindowPtr pLayerWin; Bool anyMarked = FALSE; int status = Success; + CompClientWindowPtr ccw; if (pWin == cs->pOverlayWin) { return Success; @@ -158,7 +162,7 @@ compRedirectWindow(ClientPtr pClient, WindowPtr pWin, int update) * Only one Manual update is allowed */ if (cw && update == CompositeRedirectManual) - for (CompClientWindowPtr ccw = cw->clients; ccw; ccw = ccw->next) + for (ccw = cw->clients; ccw; ccw = ccw->next) if (ccw->update == CompositeRedirectManual) return BadAccess; @@ -167,7 +171,12 @@ compRedirectWindow(ClientPtr pClient, WindowPtr pWin, int update) * The client *could* allocate multiple, but while supported, * it is not expected to be common */ - CompClientWindowPtr ccw = calloc(1, sizeof(CompClientWindowRec)); +#ifdef HAVE_NUMA + if (numa_available() != -1) + ccw = numa_alloc_interleaved(sizeof(CompClientWindowRec)); + else +#endif + ccw = calloc(1, sizeof(CompClientWindowRec)); if (!ccw) return BadAlloc; ccw->id = FakeClientID(pClient->index); @@ -176,8 +185,18 @@ compRedirectWindow(ClientPtr pClient, WindowPtr pWin, int update) * Now make sure there's a per-window structure to hang this from */ if (!cw) { +#ifdef HAVE_NUMA + if (numa_available() != -1) + cw = numa_alloc_interleaved(sizeof(CompWindowRec)); + else +#endif cw = calloc(1, sizeof(CompWindowRec)); if (!cw) { +#ifdef HAVE_NUMA + if (numa_available() != -1) + numa_free(ccw, sizeof(CompClientWindowRec)); + else +#endif free(ccw); return BadAlloc; } @@ -186,8 +205,18 @@ compRedirectWindow(ClientPtr pClient, WindowPtr pWin, int update) DamageReportNonEmpty, FALSE, pWin->drawable.pScreen, pWin); if (!cw->damage) { +#ifdef HAVE_NUMA + if (numa_available() != -1) { + numa_free(ccw, sizeof(CompClientWindowRec)); + numa_free(cw, sizeof(CompWindowRec)); + } + else { +#endif free(ccw); free(cw); +#ifdef HAVE_NUMA + } +#endif return BadAlloc; } @@ -281,6 +310,11 @@ compFreeClientWindow(WindowPtr pWin, XID id) *prev = ccw->next; if (ccw->update == CompositeRedirectManual) cw->update = CompositeRedirectAutomatic; +#ifdef HAVE_NUMA + if (numa_available() != -1) + numa_free(ccw, sizeof(CompClientWindowRec)); + else +#endif free(ccw); break; } @@ -299,6 +333,11 @@ compFreeClientWindow(WindowPtr pWin, XID id) RegionUninit(&cw->borderClip); dixSetPrivate(&pWin->devPrivates, CompWindowPrivateKey, NULL); +#ifdef HAVE_NUMA + if (numa_available() != -1) + numa_free(cw, sizeof(CompWindowRec)); + else +#endif free(cw); } else if (cw->update == CompositeRedirectAutomatic && @@ -350,12 +389,13 @@ int compRedirectSubwindows(ClientPtr pClient, WindowPtr pWin, int update) { CompSubwindowsPtr csw = GetCompSubwindows(pWin); + CompClientWindowPtr ccw; /* * Only one Manual update is allowed */ if (csw && update == CompositeRedirectManual) - for (CompClientWindowPtr ccw = csw->clients; ccw; ccw = ccw->next) + for (ccw = csw->clients; ccw; ccw = ccw->next) if (ccw->update == CompositeRedirectManual) return BadAccess; /* @@ -363,7 +403,12 @@ compRedirectSubwindows(ClientPtr pClient, WindowPtr pWin, int update) * The client *could* allocate multiple, but while supported, * it is not expected to be common */ - CompClientWindowPtr ccw = calloc(1, sizeof(CompClientWindowRec)); +#ifdef HAVE_NUMA + if (numa_available() != -1) + ccw = numa_alloc_interleaved(sizeof(CompClientWindowRec)); + else +#endif + ccw = calloc(1, sizeof(CompClientWindowRec)); if (!ccw) return BadAlloc; ccw->id = FakeClientID(pClient->index); @@ -372,8 +417,18 @@ compRedirectSubwindows(ClientPtr pClient, WindowPtr pWin, int update) * Now make sure there's a per-window structure to hang this from */ if (!csw) { +#ifdef HAVE_NUMA + if (numa_available() != -1) + csw = numa_alloc_interleaved(sizeof(CompSubwindowsRec)); + else +#endif csw = calloc(1, sizeof(CompSubwindowsRec)); if (!csw) { +#ifdef HAVE_NUMA + if (numa_available() != -1) + numa_free(ccw, sizeof(CompClientWindowRec)); + else +#endif free(ccw); return BadAlloc; } @@ -391,9 +446,19 @@ compRedirectSubwindows(ClientPtr pClient, WindowPtr pWin, int update) for (WindowPtr pSib = pChild->nextSib; pSib; pSib = pSib->nextSib) (void) compUnredirectWindow(pClient, pSib, update); if (!csw->clients) { +#ifdef HAVE_NUMA + if (numa_available() != -1) + numa_free(csw, sizeof(CompSubwindowsRec)); + else +#endif free(csw); dixSetPrivate(&pWin->devPrivates, CompSubwindowsPrivateKey, 0); } +#ifdef HAVE_NUMA + if (numa_available() != -1) + numa_free(ccw, sizeof(CompClientWindowRec)); + else +#endif free(ccw); return ret; } @@ -454,6 +519,11 @@ compFreeClientSubwindows(WindowPtr pWin, XID id) pChild; pChild = pChild->prevSib) (void) compUnredirectWindow(pClient, pChild, ccw->update); +#ifdef HAVE_NUMA + if (numa_available() != -1) + numa_free(ccw, sizeof(CompClientWindowRec)); + else +#endif free(ccw); break; } @@ -464,6 +534,11 @@ compFreeClientSubwindows(WindowPtr pWin, XID id) */ if (!csw->clients) { dixSetPrivate(&pWin->devPrivates, CompSubwindowsPrivateKey, NULL); +#ifdef HAVE_NUMA + if (numa_available() != -1) + numa_free(csw, sizeof(CompSubwindowsRec)); + else +#endif free(csw); } } diff --git a/dix/main.c b/dix/main.c index 8c55f11967..35e703d119 100644 --- a/dix/main.c +++ b/dix/main.c @@ -153,6 +153,7 @@ dix_main(int argc, char *argv[], char *envp[]) InitBlockAndWakeupHandlers(); /* Perform any operating system dependent initializations you'd like */ OsInit(); + OsNumaInit(); CreateWellKnownSockets(); for (int i = 1; i < LimitClients; i++) diff --git a/glamor/glamor.c b/glamor/glamor.c index a1a9348bf0..55d061d44c 100644 --- a/glamor/glamor.c +++ b/glamor/glamor.c @@ -35,6 +35,9 @@ #include #include #include +#ifdef HAVE_NUMA +#include +#endif #include "dix/screen_hooks_priv.h" #include "os/bug_priv.h" @@ -649,6 +652,11 @@ glamor_init(ScreenPtr screen, unsigned int flags) ErrorF("glamor_init: Invalid flags %x\n", flags); return FALSE; } +#ifdef HAVE_NUMA + if (numa_available() != -1) + glamor_priv = numa_alloc_interleaved(sizeof(*glamor_priv)); + else +#endif glamor_priv = calloc(1, sizeof(*glamor_priv)); if (glamor_priv == NULL) return FALSE; @@ -907,6 +915,11 @@ glamor_init(ScreenPtr screen, unsigned int flags) return TRUE; fail: +#ifdef HAVE_NUMA + if (numa_available() != -1) + numa_free(glamor_priv, sizeof(*glamor_priv)); + else +#endif free(glamor_priv); glamor_set_screen_private(screen, NULL); return FALSE; @@ -920,6 +933,11 @@ glamor_release_screen_priv(ScreenPtr screen) glamor_priv = glamor_get_screen_private(screen); glamor_fini_vbo(screen); glamor_pixmap_fini(screen); +#ifdef HAVE_NUMA + if (numa_available() != -1) + numa_free(glamor_priv, sizeof(*glamor_priv)); + else +#endif free(glamor_priv); glamor_set_screen_private(screen, NULL); diff --git a/glamor/glamor_fbo.c b/glamor/glamor_fbo.c index c7576a1538..4f125db5c1 100644 --- a/glamor/glamor_fbo.c +++ b/glamor/glamor_fbo.c @@ -29,6 +29,9 @@ #include #include +#ifdef HAVE_NUMA +#include +#endif #include "glamor/glamor_priv.h" #include "os/bug_priv.h" @@ -44,6 +47,11 @@ glamor_destroy_fbo(glamor_screen_private *glamor_priv, if (fbo->tex) glDeleteTextures(1, &fbo->tex); +#ifdef HAVE_NUMA + if (numa_available() != -1) + numa_free(fbo, sizeof(*fbo)); + else +#endif free(fbo); } @@ -103,6 +111,11 @@ glamor_create_fbo_from_tex(glamor_screen_private *glamor_priv, const struct glamor_format *f = glamor_format_for_pixmap(pixmap); glamor_pixmap_fbo *fbo; +#ifdef HAVE_NUMA + if (numa_available() != -1) + fbo = numa_alloc_interleaved(sizeof(*fbo)); + else +#endif fbo = calloc(1, sizeof(*fbo)); if (fbo == NULL) return NULL; @@ -193,12 +206,27 @@ glamor_create_fbo_array(glamor_screen_private *glamor_priv, block_wcnt = (w + block_w - 1) / block_w; block_hcnt = (h + block_h - 1) / block_h; +#ifdef HAVE_NUMA + if (numa_available() != -1) { + box_array = numa_alloc_interleaved(block_wcnt * block_hcnt * sizeof(box_array[0])); + fbo_array = numa_alloc_interleaved(block_wcnt * block_hcnt * sizeof(glamor_pixmap_fbo *)); + } + else { +#endif box_array = calloc(block_wcnt * block_hcnt, sizeof(box_array[0])); + fbo_array = calloc(block_wcnt * block_hcnt, sizeof(glamor_pixmap_fbo *)); +#ifdef HAVE_NUMA + } +#endif if (box_array == NULL) return NULL; - fbo_array = calloc(block_wcnt * block_hcnt, sizeof(glamor_pixmap_fbo *)); if (fbo_array == NULL) { +#ifdef HAVE_NUMA + if (numa_available() != -1) + numa_free(box_array, block_wcnt * block_hcnt * sizeof(box_array[0])); + else +#endif free(box_array); return FALSE; } @@ -239,8 +267,18 @@ glamor_create_fbo_array(glamor_screen_private *glamor_priv, for (i = 0; i < block_wcnt * block_hcnt; i++) if (fbo_array[i]) glamor_destroy_fbo(glamor_priv, fbo_array[i]); +#ifdef HAVE_NUMA + if (numa_available() != -1) { + numa_free(box_array, block_wcnt * block_hcnt * sizeof(box_array[0])); + numa_free(fbo_array, block_wcnt * block_hcnt * sizeof(glamor_pixmap_fbo *)); + } + else { +#endif free(box_array); free(fbo_array); +#ifdef HAVE_NUMA + } +#endif return NULL; } @@ -317,6 +355,11 @@ glamor_pixmap_destroy_fbo(PixmapPtr pixmap) for (i = 0; i < priv->block_wcnt * priv->block_hcnt; i++) glamor_destroy_fbo(glamor_priv, priv->fbo_array[i]); +#ifdef HAVE_NUMA + if (numa_available() != -1) + numa_free(priv->fbo_array, priv->block_wcnt * priv->block_hcnt * sizeof(glamor_pixmap_fbo *)); + else +#endif free(priv->fbo_array); priv->fbo_array = NULL; } diff --git a/hw/xfree86/common/xf86Config.c b/hw/xfree86/common/xf86Config.c index 79d46569a7..06f4d4f9f3 100644 --- a/hw/xfree86/common/xf86Config.c +++ b/hw/xfree86/common/xf86Config.c @@ -46,6 +46,9 @@ #include #include #include +#ifdef HAVE_NUMA +#include +#endif #include "dix/dix_priv.h" #include "dix/resource_priv.h" @@ -181,6 +184,11 @@ xf86ValidateFontPath(char *path) int flag; int dirlen; +#ifdef HAVE_NUMA + if (numa_available() != -1) + tmp_path = numa_alloc_interleaved(strlen(path) + 1); + else +#endif tmp_path = calloc(1, strlen(path) + 1); out_pnt = tmp_path; path_elem = NULL; diff --git a/hw/xfree86/common/xf86Option.c b/hw/xfree86/common/xf86Option.c index 75618afa8a..cbb9694aef 100644 --- a/hw/xfree86/common/xf86Option.c +++ b/hw/xfree86/common/xf86Option.c @@ -43,6 +43,9 @@ #include "xf86Parser.h" #include "xf86platformBus_priv.h" #include "optionstr.h" +#ifdef HAVE_NUMA +#include +#endif static Bool ParseOptionValue(int scrnIndex, XF86OptionPtr options, OptionInfoPtr p, Bool markUsed); @@ -843,11 +846,17 @@ xf86NormalizeName(const char *s) { char *q; const char *p; + char *ret; if (s == NULL) return NULL; - char *ret = calloc(1, strlen(s) + 1); +#ifdef HAVE_NUMA + if (numa_available() != -1) + ret = numa_alloc_interleaved(strlen(s) + 1); + else +#endif + ret = calloc(1, strlen(s) + 1); if (!ret) return NULL; for (p = s, q = ret; *p != 0; p++) { diff --git a/hw/xfree86/ddc/ddc.c b/hw/xfree86/ddc/ddc.c index 7989f72b08..55a77db87a 100644 --- a/hw/xfree86/ddc/ddc.c +++ b/hw/xfree86/ddc/ddc.c @@ -12,6 +12,9 @@ #include #include "os/osdep.h" +#ifdef HAVE_NUMA +#include +#endif #include "misc.h" #include "xf86.h" @@ -97,13 +100,19 @@ resort(unsigned char *s_block) { unsigned char *d_ptr, *d_end, *s_ptr, *s_end; unsigned char tmp; + unsigned char *d_new; s_ptr = find_header(s_block); if (!s_ptr) return NULL; s_end = s_block + EDID1_LEN; - unsigned char *d_new = calloc(1, EDID1_LEN); +#ifdef HAVE_NUMA + if (numa_available() != -1) + d_new = numa_alloc_interleaved(EDID1_LEN); + else +#endif + d_new = calloc(1, EDID1_LEN); if (!d_new) return NULL; d_end = d_new + EDID1_LEN; @@ -156,6 +165,11 @@ GetEDID_DDC1(unsigned int *s_ptr) return NULL; s_end = s_ptr + NUM; s_pos = s_ptr + s_start; +#ifdef HAVE_NUMA + if (numa_available() != -1) + d_block = numa_alloc_interleaved(EDID1_LEN); + else +#endif d_block = calloc(1, EDID1_LEN); if (!d_block) return NULL; @@ -191,7 +205,13 @@ FetchEDID_DDC1(register ScrnInfoPtr pScrn, int count = NUM; unsigned int *ptr, *xp; - ptr = xp = calloc(NUM, sizeof(int)); +#ifdef HAVE_NUMA + if (numa_available() != -1) + ptr = numa_alloc_interleaved(NUM * sizeof(int)); + else +#endif + ptr = calloc(NUM, sizeof(int)); + xp = ptr; if (!ptr) return NULL; @@ -276,6 +296,11 @@ xf86DoEDID_DDC1(ScrnInfoPtr pScrn, DDC1SetSpeedProc DDC1SetSpeed, Bool noddc = FALSE, noddc1 = FALSE; OptionInfoPtr options; +#ifdef HAVE_NUMA + if (numa_available() != -1) + options = numa_alloc_interleaved(sizeof(DDCOptions)); + else +#endif options = XNFalloc(sizeof(DDCOptions)); (void) memcpy(options, DDCOptions, sizeof(DDCOptions)); xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, options); @@ -418,7 +443,13 @@ xf86DoEEDID(ScrnInfoPtr pScrn, I2CBusPtr pBus, Bool complete) /* Default DDC and DDC2 to enabled. */ Bool noddc = FALSE, noddc2 = FALSE; - OptionInfoPtr options = calloc(1, sizeof(DDCOptions)); + OptionInfoPtr options; +#ifdef HAVE_NUMA + if (numa_available() != -1) + options = numa_alloc_interleaved(sizeof(DDCOptions)); + else +#endif + options = calloc(1, sizeof(DDCOptions)); if (!options) return NULL; memcpy(options, DDCOptions, sizeof(DDCOptions)); @@ -434,6 +465,11 @@ xf86DoEEDID(ScrnInfoPtr pScrn, I2CBusPtr pBus, Bool complete) if (!(dev = DDC2Init(pBus))) return NULL; +#ifdef HAVE_NUMA + if (numa_available() != -1) + EDID_block = numa_alloc_interleaved(EDID1_LEN); + else +#endif EDID_block = calloc(1, EDID1_LEN); if (!EDID_block) return NULL; diff --git a/include/os.h b/include/os.h index 519c465ce3..7435b3f372 100644 --- a/include/os.h +++ b/include/os.h @@ -189,6 +189,8 @@ Xstrdup(const char *s); extern _X_EXPORT char * XNFstrdup(const char *s); +extern _X_EXPORT void Xfree(void *ptr); + /* Include new X*asprintf API */ #include "Xprintf.h" diff --git a/meson.build b/meson.build index 11c2915352..2ed75796d1 100644 --- a/meson.build +++ b/meson.build @@ -687,6 +687,20 @@ if get_option('xselinux') != 'false' endif endif +numa_dep = dependency('numa', required: get_option('numa')) +if get_option('numa') + if numa_dep.found() + conf_data.set('HAVE_NUMA', 1) + common_dep += numa_dep + message('NUMA support: YES') + else + if get_option('numa') + error('NUMA support requested but libnuma not found') + endif + message('NUMA support: NO') + endif +endif + socket_dep = [] if host_machine.system() == 'windows' socket_dep = meson.get_compiler('c').find_library('ws2_32') diff --git a/meson_options.txt b/meson_options.txt index a375ac7835..b5165e5ecb 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -14,6 +14,7 @@ option('xwin', type: 'combo', choices: ['true', 'false', 'auto'], value: 'auto', description: 'Enable XWin X server') option('xquartz', type: 'combo', choices: ['true', 'false', 'auto'], value: 'auto', description: 'Enable Xquartz X server') +option('numa', type: 'boolean', value: false, description: 'Enable NUMA support') option('kdrive_kbd', type: 'boolean', value: true, description: 'Build kbd driver for kdrive') diff --git a/os/alloc.c b/os/alloc.c index 0a00c6386e..6da49a5783 100644 --- a/os/alloc.c +++ b/os/alloc.c @@ -6,14 +6,89 @@ #include #include +#ifdef HAVE_NUMA +#include +#endif #include "include/os.h" #include "os/osdep.h" +#ifdef HAVE_NUMA +static inline void * +numa_alloc_impl(size_t size) +{ + void *ptr; + size_t total_size = size + sizeof(size_t); + + if (numa_available() != -1) + ptr = numa_alloc_interleaved(total_size); + else + ptr = malloc(total_size); + + if (!ptr) + return NULL; + + *(size_t *)ptr = size; + return (char *)ptr + sizeof(size_t); +} + +static inline void * +numa_calloc_impl(size_t nmemb, size_t size) +{ + void *ptr; + size_t total_size = (nmemb * size) + sizeof(size_t); + + if (numa_available() != -1) + ptr = numa_alloc_interleaved(total_size); + else + ptr = malloc(total_size); + + if (!ptr) + return NULL; + + *(size_t *)ptr = nmemb * size; + memset((char *)ptr + sizeof(size_t), 0, nmemb * size); + return (char *)ptr + sizeof(size_t); +} + +static inline void * +numa_realloc_impl(void *ptr, size_t size) +{ + void *real_ptr; + void *new_ptr; + size_t old_size; + size_t total_size = size + sizeof(size_t); + + if (!ptr) + return numa_alloc_impl(size); + + real_ptr = (char *)ptr - sizeof(size_t); + old_size = *(size_t *)real_ptr; + + if (numa_available() != -1) + new_ptr = numa_realloc(real_ptr, old_size + sizeof(size_t), total_size); + else + new_ptr = realloc(real_ptr, total_size); + + if (!new_ptr) + return NULL; + + *(size_t *)new_ptr = size; + return (char *)new_ptr + sizeof(size_t); +} +#endif + void * XNFalloc(unsigned long amount) { - void *ptr = calloc(1, amount); + void *ptr; + +#ifdef HAVE_NUMA + if (numa_available() != -1) + ptr = numa_alloc_impl(amount); + else +#endif + ptr = calloc(1, amount); if (!ptr) FatalError("Out of memory"); @@ -33,7 +108,14 @@ XNFcalloc(unsigned long amount) void * XNFcallocarray(size_t nmemb, size_t size) { - void *ret = calloc(nmemb, size); + void *ret; + +#ifdef HAVE_NUMA + if (numa_available() != -1) + ret = numa_calloc_impl(nmemb, size); + else +#endif + ret = calloc(nmemb, size); if (!ret) FatalError("XNFcalloc: Out of memory"); @@ -43,7 +125,14 @@ XNFcallocarray(size_t nmemb, size_t size) void * XNFrealloc(void *ptr, unsigned long amount) { - void *ret = realloc(ptr, amount); + void *ret; + +#ifdef HAVE_NUMA + if (numa_available() != -1) + ret = numa_realloc_impl(ptr, amount); + else +#endif + ret = realloc(ptr, amount); if (!ret) FatalError("XNFrealloc: Out of memory"); @@ -53,9 +142,33 @@ XNFrealloc(void *ptr, unsigned long amount) void * XNFreallocarray(void *ptr, size_t nmemb, size_t size) { - void *ret = reallocarray(ptr, nmemb, size); + void *ret; + +#ifdef HAVE_NUMA + if (numa_available() != -1) + ret = numa_realloc_impl(ptr, nmemb * size); + else +#endif + ret = reallocarray(ptr, nmemb, size); if (!ret) FatalError("XNFreallocarray: Out of memory"); return ret; } + +void +Xfree(void *ptr) +{ + if (!ptr) + return; + +#ifdef HAVE_NUMA + if (numa_available() != -1) { + void *real_ptr = (char *)ptr - sizeof(size_t); + size_t size = *(size_t *)real_ptr; + numa_free(real_ptr, size + sizeof(size_t)); + } + else +#endif + free(ptr); +} diff --git a/os/connection.c b/os/connection.c index 5d5fcb0990..f194023ced 100644 --- a/os/connection.c +++ b/os/connection.c @@ -122,6 +122,10 @@ SOFTWARE. #include "xdmcp.h" #endif +#ifdef HAVE_NUMA +#include +#endif + #define MAX_CONNECTIONS (1<<16) #define OS_COMM_GRAB_IMPERVIOUS 1 @@ -279,6 +283,11 @@ CreateWellKnownSockets(void) return; // mostly to keep GCC from complaining about too large alloc } +#ifdef HAVE_NUMA + if (numa_available() != -1) + ListenTransFds = numa_alloc_interleaved(ListenTransCount * sizeof(int)); + else +#endif ListenTransFds = calloc(ListenTransCount, sizeof(int)); if (ListenTransFds == NULL) FatalError ("Failed to create listening socket array"); @@ -575,14 +584,25 @@ static ClientPtr AllocNewConnection(XtransConnInfo trans_conn, int fd, CARD32 conn_time) { ClientPtr client; + OsCommPtr oc; - OsCommPtr oc = calloc(1, sizeof(OsCommRec)); +#ifdef HAVE_NUMA + if (numa_available() != -1) + oc = numa_alloc_interleaved(sizeof(OsCommRec)); + else +#endif + oc = calloc(1, sizeof(OsCommRec)); if (!oc) return NULL; oc->trans_conn = trans_conn; oc->fd = fd; oc->conn_time = conn_time; if (!(client = NextAvailableClient((void *) oc))) { +#ifdef HAVE_NUMA + if (numa_available() != -1) + numa_free(oc, sizeof(OsCommRec)); + else +#endif free(oc); return NULL; } @@ -737,6 +757,11 @@ CloseDownConnection(ClientPtr client) FlushClient(client, oc); CloseDownFileDescriptor(oc); FreeOsBuffers(oc); +#ifdef HAVE_NUMA + if (numa_available() != -1) + numa_free(client->osPrivate, sizeof(OsCommRec)); + else +#endif free(client->osPrivate); client->osPrivate = (void *) NULL; if (auditTrailLevel > 1) @@ -778,6 +803,11 @@ SetNotifyFd(int fd, NotifyFdProcPtr notify, int mask, void *data) if (mask == 0) return TRUE; +#ifdef HAVE_NUMA + if (numa_available() != -1) + n = numa_alloc_interleaved(sizeof(struct notify_fd)); + else +#endif n = calloc(1, sizeof (struct notify_fd)); if (!n) return FALSE; @@ -789,6 +819,11 @@ SetNotifyFd(int fd, NotifyFdProcPtr notify, int mask, void *data) if (mask == 0) { ospoll_remove(server_poll, fd); +#ifdef HAVE_NUMA + if (numa_available() != -1) + numa_free(n, sizeof(struct notify_fd)); + else +#endif free(n); } else { int listen = mask & ~n->mask; diff --git a/os/osdep.h b/os/osdep.h index 431492e791..6f0035e254 100644 --- a/os/osdep.h +++ b/os/osdep.h @@ -48,6 +48,10 @@ SOFTWARE. #include +#ifdef HAVE_NUMA +#include +#endif + #include #include @@ -135,6 +139,7 @@ typedef void (*OsSigHandlerPtr) (int sig); OsSigHandlerPtr OsSignal(int sig, OsSigHandlerPtr handler); void OsInit(void); +void OsNumaInit(void); _X_EXPORT /* needed by the int10 module, but should not be used by OOT drivers */ void OsBlockSignals(void); diff --git a/os/utils.c b/os/utils.c index c8685cddca..9793cc0337 100644 --- a/os/utils.c +++ b/os/utils.c @@ -146,6 +146,17 @@ sig_atomic_t inSignalContext = FALSE; static clockid_t clockid; #endif +void +OsNumaInit(void) +{ +#ifdef HAVE_NUMA + if (numa_available() != -1) { + numa_set_interleave_mask(numa_all_nodes_ptr); + numa_set_localalloc(); + } +#endif +} + OsSigHandlerPtr OsSignal(int sig, OsSigHandlerPtr handler) { diff --git a/render/glyph.c b/render/glyph.c index f624be97bf..069355948c 100644 --- a/render/glyph.c +++ b/render/glyph.c @@ -27,6 +27,9 @@ #include "dix/screenint_priv.h" #include "os/bug_priv.h" #include "os/xsha1.h" +#ifdef HAVE_NUMA +#include +#endif #include "misc.h" #include "scrnintstr.h" @@ -342,10 +345,16 @@ AllocateGlyph(xGlyphInfo * gi, int fdepth) { int size; int head_size; + GlyphPtr glyph; head_size = sizeof(GlyphRec) + screenInfo.numScreens * sizeof(PicturePtr); size = (head_size + dixPrivatesSize(PRIVATE_GLYPH)); - GlyphPtr glyph = calloc(1, size); +#ifdef HAVE_NUMA + if (numa_available() != -1) + glyph = numa_alloc_interleaved(size); + else +#endif + glyph = calloc(1, size); if (!glyph) return 0; glyph->refcnt = 1; @@ -383,6 +392,11 @@ static Bool AllocateGlyphHash(GlyphHashPtr hash, GlyphHashSetPtr hashSet) { assert(hashSet); +#ifdef HAVE_NUMA + if (numa_available() != -1) + hash->table = numa_alloc_interleaved(hashSet->size * sizeof(GlyphRefRec)); + else +#endif hash->table = calloc(hashSet->size, sizeof(GlyphRefRec)); if (!hash->table) return FALSE; @@ -424,6 +438,11 @@ ResizeGlyphHash(GlyphHashPtr hash, CARD32 change, Bool global) ++newHash.tableEntries; } } +#ifdef HAVE_NUMA + if (numa_available() != -1) + numa_free(hash->table, oldSize * sizeof(GlyphRefRec)); + else +#endif free(hash->table); } *hash = newHash; @@ -479,12 +498,22 @@ FreeGlyphSet(void *value, XID gid) FreeGlyph(glyph, glyphSet->fdepth); } if (!globalGlyphs[glyphSet->fdepth].tableEntries) { +#ifdef HAVE_NUMA + if (numa_available() != -1) + numa_free(globalGlyphs[glyphSet->fdepth].table, globalGlyphs[glyphSet->fdepth].hashSet->size * sizeof(GlyphRefRec)); + else +#endif free(globalGlyphs[glyphSet->fdepth].table); globalGlyphs[glyphSet->fdepth].table = 0; globalGlyphs[glyphSet->fdepth].hashSet = 0; } else ResizeGlyphHash(&globalGlyphs[glyphSet->fdepth], 0, TRUE); +#ifdef HAVE_NUMA + if (numa_available() != -1) + numa_free(table, tableSize * sizeof(GlyphRefRec)); + else +#endif free(table); dixFreeObjectWithPrivates(glyphSet, PRIVATE_GLYPHSET); } diff --git a/render/mipict.c b/render/mipict.c index 02faaca066..f6f47d55c2 100644 --- a/render/mipict.c +++ b/render/mipict.c @@ -24,6 +24,9 @@ #include #include "os/osdep.h" +#ifdef HAVE_NUMA +#include +#endif #include "scrnintstr.h" #include "gcstruct.h" @@ -508,6 +511,11 @@ miTriStrip(CARD8 op, int ntri; ntri = npoints - 2; +#ifdef HAVE_NUMA + if (numa_available() != -1) + tris = numa_alloc_interleaved(ntri * sizeof(xTriangle)); + else +#endif tris = calloc(ntri, sizeof(xTriangle)); if (!tris) return; @@ -518,6 +526,11 @@ miTriStrip(CARD8 op, tri->p3 = points[2]; } CompositeTriangles(op, pSrc, pDst, maskFormat, xSrc, ySrc, ntri, tris); +#ifdef HAVE_NUMA + if (numa_available() != -1) + numa_free(tris, ntri * sizeof(xTriangle)); + else +#endif free(tris); } @@ -533,6 +546,11 @@ miTriFan(CARD8 op, int ntri; ntri = npoints - 2; +#ifdef HAVE_NUMA + if (numa_available() != -1) + tris = numa_alloc_interleaved(ntri * sizeof(xTriangle)); + else +#endif tris = calloc(ntri, sizeof(xTriangle)); if (!tris) return; @@ -544,6 +562,11 @@ miTriFan(CARD8 op, tri->p3 = points[1]; } CompositeTriangles(op, pSrc, pDst, maskFormat, xSrc, ySrc, ntri, tris); +#ifdef HAVE_NUMA + if (numa_available() != -1) + numa_free(tris, ntri * sizeof(xTriangle)); + else +#endif free(tris); } diff --git a/render/picture.c b/render/picture.c index 464955721c..62ae541b8f 100644 --- a/render/picture.c +++ b/render/picture.c @@ -28,6 +28,9 @@ #include "dix/screen_hooks_priv.h" #include "include/extinit.h" #include "os/osdep.h" +#ifdef HAVE_NUMA +#include +#endif #include "misc.h" #include "scrnintstr.h" @@ -87,8 +90,18 @@ static void PictureScreenClose(CallbackListPtr *pcbl, ScreenPtr pScreen, void *u (*ps->CloseIndexed) (pScreen, &ps->formats[n]); GlyphUninit(pScreen); SetPictureScreen(pScreen, 0); +#ifdef HAVE_NUMA + if (numa_available() != -1) { + numa_free(ps->formats, ps->nformats * sizeof(PictFormatRec)); + numa_free(ps, sizeof(PictureScreenRec)); + } + else { +#endif free(ps->formats); free(ps); +#ifdef HAVE_NUMA + } +#endif dixScreenUnhookPostClose(pScreen, PictureScreenClose); } @@ -284,6 +297,11 @@ PictureCreateDefaultFormats(ScreenPtr pScreen, int *nformatp) } } +#ifdef HAVE_NUMA + if (numa_available() != -1) + pFormats = numa_alloc_interleaved(nformats * sizeof(PictFormatRec)); + else +#endif pFormats = calloc(nformats, sizeof(PictFormatRec)); if (!pFormats) return 0; @@ -634,6 +652,11 @@ PictureInit(ScreenPtr pScreen, PictFormatPtr formats, int nformats) int i; for (i = 0; i < n; i++) FreeResource(formats[i].id, X11_RESTYPE_NONE); +#ifdef HAVE_NUMA + if (numa_available() != -1) + numa_free(formats, nformats * sizeof(PictFormatRec)); + else +#endif free(formats); return FALSE; } @@ -663,8 +686,19 @@ PictureInit(ScreenPtr pScreen, PictFormatPtr formats, int nformats) } formats[n].format = PIXMAN_FORMAT(0, type, a, r, g, b); } - PictureScreenPtr ps = calloc(1, sizeof(PictureScreenRec)); + PictureScreenPtr ps; +#ifdef HAVE_NUMA + if (numa_available() != -1) + ps = numa_alloc_interleaved(sizeof(PictureScreenRec)); + else +#endif + ps = calloc(1, sizeof(PictureScreenRec)); if (!ps) { +#ifdef HAVE_NUMA + if (numa_available() != -1) + numa_free(formats, nformats * sizeof(PictFormatRec)); + else +#endif free(formats); return FALSE; } @@ -690,8 +724,18 @@ PictureInit(ScreenPtr pScreen, PictFormatPtr formats, int nformats) if (!PictureSetDefaultFilters(pScreen)) { PictureResetFilters(pScreen); SetPictureScreen(pScreen, 0); +#ifdef HAVE_NUMA + if (numa_available() != -1) { + numa_free(formats, nformats * sizeof(PictFormatRec)); + numa_free(ps, sizeof(PictureScreenRec)); + } + else { +#endif free(formats); free(ps); +#ifdef HAVE_NUMA + } +#endif return FALSE; } @@ -813,6 +857,11 @@ initGradient(SourcePictPtr pGradient, int stopCount, dpos = stopPoints[i]; } +#ifdef HAVE_NUMA + if (numa_available() != -1) + pGradient->gradient.stops = numa_alloc_interleaved(stopCount * sizeof(PictGradientStop)); + else +#endif pGradient->gradient.stops = calloc(stopCount, sizeof(PictGradientStop)); if (!pGradient->gradient.stops) { *error = BadAlloc; @@ -858,6 +907,11 @@ CreateSolidPicture(Picture pid, xRenderColor * color, int *error) } pPicture->id = pid; +#ifdef HAVE_NUMA + if (numa_available() != -1) + pPicture->pSourcePict = numa_alloc_interleaved(sizeof(SourcePict)); + else +#endif pPicture->pSourcePict = calloc(1, sizeof(SourcePict)); if (!pPicture->pSourcePict) { *error = BadAlloc; @@ -889,6 +943,11 @@ CreateLinearGradientPicture(Picture pid, xPointFixed * p1, xPointFixed * p2, } pPicture->id = pid; +#ifdef HAVE_NUMA + if (numa_available() != -1) + pPicture->pSourcePict = numa_alloc_interleaved(sizeof(SourcePict)); + else +#endif pPicture->pSourcePict = calloc(1, sizeof(SourcePict)); if (!pPicture->pSourcePict) { *error = BadAlloc; @@ -929,6 +988,11 @@ CreateRadialGradientPicture(Picture pid, xPointFixed * inner, } pPicture->id = pid; +#ifdef HAVE_NUMA + if (numa_available() != -1) + pPicture->pSourcePict = numa_alloc_interleaved(sizeof(SourcePict)); + else +#endif pPicture->pSourcePict = calloc(1, sizeof(SourcePict)); if (!pPicture->pSourcePict) { *error = BadAlloc; @@ -972,6 +1036,11 @@ CreateConicalGradientPicture(Picture pid, xPointFixed * center, xFixed angle, } pPicture->id = pid; +#ifdef HAVE_NUMA + if (numa_available() != -1) + pPicture->pSourcePict = numa_alloc_interleaved(sizeof(SourcePict)); + else +#endif pPicture->pSourcePict = calloc(1, sizeof(SourcePict)); if (!pPicture->pSourcePict) { *error = BadAlloc; @@ -1323,6 +1392,11 @@ SetPictureTransform(PicturePtr pPicture, PictTransform * transform) if (transform) { if (!pPicture->transform) { +#ifdef HAVE_NUMA + if (numa_available() != -1) + pPicture->transform = numa_alloc_interleaved(sizeof(PictTransform)); + else +#endif pPicture->transform = calloc(1, sizeof(PictTransform)); if (!pPicture->transform) return BadAlloc; @@ -1330,6 +1404,11 @@ SetPictureTransform(PicturePtr pPicture, PictTransform * transform) *pPicture->transform = *transform; } else { +#ifdef HAVE_NUMA + if (numa_available() != -1) + numa_free(pPicture->transform, sizeof(PictTransform)); + else +#endif free(pPicture->transform); pPicture->transform = NULL; } @@ -1374,13 +1453,35 @@ FreePicture(void *value, XID pid) PicturePtr pPicture = (PicturePtr) value; if (--pPicture->refcnt == 0) { +#ifdef HAVE_NUMA + if (numa_available() != -1) { + if (pPicture->transform) + numa_free(pPicture->transform, sizeof(PictTransform)); + if (pPicture->filter_params) + numa_free(pPicture->filter_params, pPicture->filter_nparams * sizeof(xFixed)); + } + else { +#endif free(pPicture->transform); free(pPicture->filter_params); +#ifdef HAVE_NUMA + } +#endif if (pPicture->pSourcePict) { if (pPicture->pSourcePict->type != SourcePictTypeSolidFill) +#ifdef HAVE_NUMA + if (numa_available() != -1) + numa_free(pPicture->pSourcePict->linear.stops, pPicture->pSourcePict->linear.nstops * sizeof(PictGradientStop)); + else +#endif free(pPicture->pSourcePict->linear.stops); +#ifdef HAVE_NUMA + if (numa_available() != -1) + numa_free(pPicture->pSourcePict, sizeof(SourcePict)); + else +#endif free(pPicture->pSourcePict); }