From 0a02d8093ed7664247af8ce857cdb60065626915 Mon Sep 17 00:00:00 2001 From: michalbiesek Date: Fri, 10 Apr 2020 12:53:38 +0200 Subject: [PATCH 1/7] Add sdsdramempty function - add possibility to create a new sds explicitly on DRAM --- src/sds.c | 22 ++++++++++++++++++++-- src/sds.h | 1 + src/sdsalloc.h | 1 + 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/sds.c b/src/sds.c index 98bd2e77f0e..d7c657268f1 100644 --- a/src/sds.c +++ b/src/sds.c @@ -41,6 +41,9 @@ const char *SDS_NOINIT = "SDS_NOINIT"; +#define SDS_GENERAL_VARIANT 0 +#define SDS_DRAM_VARIANT 1 + static inline int sdsHdrSize(char type) { switch(type&SDS_TYPE_MASK) { case SDS_TYPE_5: @@ -86,7 +89,7 @@ static inline char sdsReqType(size_t string_size) { * You can print the string with printf() as there is an implicit \0 at the * end of the string. However the string is binary safe and can contain * \0 characters in the middle, as the length is stored in the sds header. */ -sds sdsnewlen(const void *init, size_t initlen) { +static sds _sdsnewlen(const void *init, size_t initlen, int on_dram) { void *sh; sds s; char type = sdsReqType(initlen); @@ -96,7 +99,8 @@ sds sdsnewlen(const void *init, size_t initlen) { int hdrlen = sdsHdrSize(type); unsigned char *fp; /* flags pointer. */ - sh = s_malloc(hdrlen+initlen+1); + sh = (on_dram == SDS_DRAM_VARIANT) ? s_dram_malloc(hdrlen+initlen+1) + : s_malloc(hdrlen+initlen+1); if (init==SDS_NOINIT) init = NULL; else if (!init) @@ -144,12 +148,26 @@ sds sdsnewlen(const void *init, size_t initlen) { return s; } +sds sdsnewlen(const void *init, size_t initlen) { + return _sdsnewlen(init, initlen, SDS_GENERAL_VARIANT); +} + +static sds sdsdramnewlen(const void *init, size_t initlen) { + return _sdsnewlen(init, initlen, SDS_DRAM_VARIANT); +} + /* Create an empty (zero length) sds string. Even in this case the string * always has an implicit null term. */ sds sdsempty(void) { return sdsnewlen("",0); } +/* Create an empty (zero length) sds string on DRAM. Even in this case the string + * always has an implicit null term. */ +sds sdsdramempty(void) { + return sdsdramnewlen("",0); +} + /* Create a new sds string starting from a null terminated C string. */ sds sdsnew(const char *init) { size_t initlen = (init == NULL) ? 0 : strlen(init); diff --git a/src/sds.h b/src/sds.h index adcc12c0a76..5bdeedad78c 100644 --- a/src/sds.h +++ b/src/sds.h @@ -218,6 +218,7 @@ static inline void sdssetalloc(sds s, size_t newlen) { sds sdsnewlen(const void *init, size_t initlen); sds sdsnew(const char *init); sds sdsempty(void); +sds sdsdramempty(void); sds sdsdup(const sds s); void sdsfree(sds s); sds sdsgrowzero(sds s, size_t len); diff --git a/src/sdsalloc.h b/src/sdsalloc.h index c04ff2a0a5c..7c7a6a80f09 100644 --- a/src/sdsalloc.h +++ b/src/sdsalloc.h @@ -43,5 +43,6 @@ #define s_malloc zmalloc #define s_realloc zrealloc #define s_free zfree +#define s_dram_malloc zmalloc_dram #endif From f915e08e56fc292885cd1990109bd15704ea493a Mon Sep 17 00:00:00 2001 From: michalbiesek Date: Fri, 10 Apr 2020 12:53:56 +0200 Subject: [PATCH 2/7] Move client buffers explicitly to DRAM --- src/networking.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/networking.c b/src/networking.c index 4c394af70a9..451ad22eaba 100644 --- a/src/networking.c +++ b/src/networking.c @@ -108,8 +108,8 @@ client *createClient(connection *conn) { c->name = NULL; c->bufpos = 0; c->qb_pos = 0; - c->querybuf = sdsempty(); - c->pending_querybuf = sdsempty(); + c->querybuf = sdsdramempty(); + c->pending_querybuf = sdsdramempty(); c->querybuf_peak = 0; c->reqtype = 0; c->argc = 0; From e2613c9c6ab35a785fc03d14a6236d1771f87bef Mon Sep 17 00:00:00 2001 From: Jakub Schmiegel Date: Tue, 17 Mar 2020 13:42:10 +0100 Subject: [PATCH 3/7] Allocate Client structure from DRAM --- src/networking.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/networking.c b/src/networking.c index 451ad22eaba..bc6830fb82f 100644 --- a/src/networking.c +++ b/src/networking.c @@ -85,7 +85,7 @@ void linkClient(client *c) { } client *createClient(connection *conn) { - client *c = zmalloc(sizeof(client)); + client *c = zmalloc_dram(sizeof(client)); /* passing NULL as conn it is possible to create a non connected client. * This is useful since all the commands needs to be executed @@ -1151,7 +1151,7 @@ void freeClient(client *c) { zfree(c->argv); freeClientMultiState(c); sdsfree(c->peerid); - zfree(c); + zfree_dram(c); } /* Schedule a client to free it at a safe time in the serverCron() function. From b5dd96c0bac4d4b30eda5bd500fda2ca32ce8589 Mon Sep 17 00:00:00 2001 From: Jakub Schmiegel Date: Tue, 17 Mar 2020 13:46:14 +0100 Subject: [PATCH 4/7] Allocate Dict Iterator on DRAM --- src/dict.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dict.c b/src/dict.c index 93e6c39a75d..54fdab28904 100644 --- a/src/dict.c +++ b/src/dict.c @@ -541,7 +541,7 @@ long long dictFingerprint(dict *d) { dictIterator *dictGetIterator(dict *d) { - dictIterator *iter = zmalloc(sizeof(*iter)); + dictIterator *iter = zmalloc_dram(sizeof(*iter)); iter->d = d; iter->table = 0; @@ -602,7 +602,7 @@ void dictReleaseIterator(dictIterator *iter) else assert(iter->fingerprint == dictFingerprint(iter->d)); } - zfree(iter); + zfree_dram(iter); } /* Return a random entry from the hash table. Useful to From 40f344fc656a547e9cacac9079e18da40301272f Mon Sep 17 00:00:00 2001 From: jschmieg Date: Thu, 19 Mar 2020 09:44:29 +0100 Subject: [PATCH 5/7] Allocate client lists on DRAM --- src/adlist.c | 9 +++++++++ src/adlist.h | 1 + src/networking.c | 12 ++++++------ 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/adlist.c b/src/adlist.c index 50b08517a5b..60c640ad6e8 100644 --- a/src/adlist.c +++ b/src/adlist.c @@ -96,6 +96,15 @@ void listRelease(list *list) zfree(list); } +/* Free the whole list from DRAM. + * + * This function can't fail. */ +void listReleaseDRAM(list *list) +{ + listEmpty(list); + zfree_dram(list); +} + /* Add a new node to the list, to head, containing the specified 'value' * pointer as value. * diff --git a/src/adlist.h b/src/adlist.h index 9d7dea7343e..ae757d0ffb3 100644 --- a/src/adlist.h +++ b/src/adlist.h @@ -73,6 +73,7 @@ typedef struct list { list *listCreate(void); list *listCreateDRAM(void); void listRelease(list *list); +void listReleaseDRAM(list *list); void listEmpty(list *list); list *listAddNodeHead(list *list, void *value); list *listAddNodeTail(list *list, void *value); diff --git a/src/networking.c b/src/networking.c index bc6830fb82f..8e9ed1452d6 100644 --- a/src/networking.c +++ b/src/networking.c @@ -133,7 +133,7 @@ client *createClient(connection *conn) { c->slave_listening_port = 0; c->slave_ip[0] = '\0'; c->slave_capa = SLAVE_CAPA_NONE; - c->reply = listCreate(); + c->reply = listCreateDRAM(); c->reply_bytes = 0; c->obuf_soft_limit_reached_time = 0; listSetFreeMethod(c->reply,freeClientReplyValue); @@ -148,9 +148,9 @@ client *createClient(connection *conn) { c->bpop.numreplicas = 0; c->bpop.reploffset = 0; c->woff = 0; - c->watched_keys = listCreate(); + c->watched_keys = listCreateDRAM(); c->pubsub_channels = dictCreate(&objectKeyPointerValueDictType,NULL); - c->pubsub_patterns = listCreate(); + c->pubsub_patterns = listCreateDRAM(); c->peerid = NULL; c->client_list_node = NULL; c->client_tracking_redirection = 0; @@ -1092,16 +1092,16 @@ void freeClient(client *c) { /* UNWATCH all the keys */ unwatchAllKeys(c); - listRelease(c->watched_keys); + listReleaseDRAM(c->watched_keys); /* Unsubscribe from all the pubsub channels */ pubsubUnsubscribeAllChannels(c,0); pubsubUnsubscribeAllPatterns(c,0); dictRelease(c->pubsub_channels); - listRelease(c->pubsub_patterns); + listReleaseDRAM(c->pubsub_patterns); /* Free data structures. */ - listRelease(c->reply); + listReleaseDRAM(c->reply); freeClientArgv(c); /* Unlink the client: this will close the socket, remove the I/O From 435806562c0801e4d77f41dab74cd7be02bff54f Mon Sep 17 00:00:00 2001 From: Jakub Schmiegel Date: Wed, 1 Apr 2020 12:21:54 +0200 Subject: [PATCH 6/7] Allocate dictionary hashtable in DRAM Applies also to Set and ZSet structures --- src/dict.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dict.c b/src/dict.c index 54fdab28904..09455821e5a 100644 --- a/src/dict.c +++ b/src/dict.c @@ -160,7 +160,7 @@ int dictExpand(dict *d, unsigned long size) /* Allocate the new hash table and initialize all pointers to NULL */ n.size = realsize; n.sizemask = realsize-1; - n.table = zcalloc(realsize*sizeof(dictEntry*)); + n.table = zcalloc_dram(realsize*sizeof(dictEntry*)); n.used = 0; /* Is this the first initialization? If so it's not really a rehashing @@ -219,7 +219,7 @@ int dictRehash(dict *d, int n) { /* Check if we already rehashed the whole table... */ if (d->ht[0].used == 0) { - zfree(d->ht[0].table); + zfree_dram(d->ht[0].table); d->ht[0] = d->ht[1]; _dictReset(&d->ht[1]); d->rehashidx = -1; From 2db3fb7696b252671ccdfdd1e72031c98a1207c1 Mon Sep 17 00:00:00 2001 From: jschmieg Date: Mon, 20 Apr 2020 15:38:06 +0200 Subject: [PATCH 7/7] Allocate and free client argv always from DRAM --- src/networking.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/networking.c b/src/networking.c index 8e9ed1452d6..07ef0c189b4 100644 --- a/src/networking.c +++ b/src/networking.c @@ -1148,7 +1148,7 @@ void freeClient(client *c) { /* Release other dynamically allocated client structure fields, * and finally release the client structure itself. */ if (c->name) decrRefCount(c->name); - zfree(c->argv); + zfree_dram(c->argv); freeClientMultiState(c); sdsfree(c->peerid); zfree_dram(c); @@ -1460,8 +1460,8 @@ int processInlineBuffer(client *c) { /* Setup argv array on client structure */ if (argc) { - if (c->argv) zfree(c->argv); - c->argv = zmalloc(sizeof(robj*)*argc); + if (c->argv) zfree_dram(c->argv); + c->argv = zmalloc_dram(sizeof(robj*)*argc); } /* Create redis objects for all arguments. */ @@ -1554,8 +1554,8 @@ int processMultibulkBuffer(client *c) { c->multibulklen = ll; /* Setup argv array on client structure */ - if (c->argv) zfree(c->argv); - c->argv = zmalloc(sizeof(robj*)*c->multibulklen); + if (c->argv) zfree_dram(c->argv); + c->argv = zmalloc_dram(sizeof(robj*)*c->multibulklen); } serverAssertWithInfo(c,NULL,c->multibulklen > 0); @@ -2472,7 +2472,7 @@ void rewriteClientCommandVector(client *c, int argc, ...) { * sure that if the same objects are reused in the new vector the * refcount gets incremented before it gets decremented. */ for (j = 0; j < c->argc; j++) decrRefCount(c->argv[j]); - zfree(c->argv); + zfree_dram(c->argv); /* Replace argv and argc with our new versions. */ c->argv = argv; c->argc = argc; @@ -2484,7 +2484,7 @@ void rewriteClientCommandVector(client *c, int argc, ...) { /* Completely replace the client command vector with the provided one. */ void replaceClientCommandVector(client *c, int argc, robj **argv) { freeClientArgv(c); - zfree(c->argv); + zfree_dram(c->argv); c->argv = argv; c->argc = argc; c->cmd = lookupCommandOrOriginal(c->argv[0]->ptr);