From 564fe08f7819b5a6fd75b6c7fa5181fa8fcdce62 Mon Sep 17 00:00:00 2001 From: Jeff Darcy Date: Thu, 27 Oct 2016 11:51:47 -0400 Subject: [PATCH 320/361] libglusterfs+transport+io-threads: fix 256KB stack abuse Some functions were allocating 64K booleans, which are (crazily) mapped to 4-byte ints, for a total of 256KB per call. Changed to use bitfields instead, so usage is now only 8KB per call. This was the impediment to changing the io-threads stack size, so that has been adjusted too. mainline: > BUG: 1418095 > Reviewed-on: https://review.gluster.org/15745 > Smoke: Gluster Build System > NetBSD-regression: NetBSD Build System > CentOS-regression: Gluster Build System > Reviewed-by: N Balachandran > Reviewed-by: Shyamsundar Ranganathan (cherry picked from commit 17d25a2a42eebd4b60c03c8f5a315f953d2c03fe) BUG: 1417815 Change-Id: I8781c4f2c8f2b830f4535e366995fac8dd0a8653 Signed-off-by: Jeff Darcy Reviewed-on: https://code.engineering.redhat.com/gerrit/101301 Tested-by: Milind Changire Reviewed-by: Atin Mukherjee --- libglusterfs/src/common-utils.c | 13 ++++------ libglusterfs/src/common-utils.h | 34 ++++++++++++++++++++++--- rpc/rpc-transport/rdma/src/name.c | 12 ++++----- rpc/rpc-transport/socket/src/name.c | 12 ++++----- xlators/performance/io-threads/src/io-threads.h | 2 +- 5 files changed, 49 insertions(+), 24 deletions(-) diff --git a/libglusterfs/src/common-utils.c b/libglusterfs/src/common-utils.c index e17dd3f..e335e94 100644 --- a/libglusterfs/src/common-utils.c +++ b/libglusterfs/src/common-utils.c @@ -3006,14 +3006,11 @@ out: } int -gf_process_reserved_ports (gf_boolean_t *ports, uint32_t ceiling) +gf_process_reserved_ports (unsigned char *ports, uint32_t ceiling) { int ret = -1; - int i = 0; - for (i = 0; i < GF_PORT_MAX; i++) { - *(ports + i) = _gf_false; - } + memset (ports, 0, GF_PORT_ARRAY_SIZE); #if defined GF_LINUX_HOST_OS char *ports_info = NULL; @@ -3049,7 +3046,7 @@ out: } gf_boolean_t -gf_ports_reserved (char *blocked_port, gf_boolean_t *ports, uint32_t ceiling) +gf_ports_reserved (char *blocked_port, unsigned char *ports, uint32_t ceiling) { gf_boolean_t result = _gf_false; char *range_port = NULL; @@ -3071,7 +3068,7 @@ gf_ports_reserved (char *blocked_port, gf_boolean_t *ports, uint32_t ceiling) } else { gf_msg_debug ("glusterfs", 0, "blocking port " "%d", tmp_port1); - ports[tmp_port1] = _gf_true; + BIT_SET (ports, tmp_port1); } } else { gf_msg ("glusterfs-socket", GF_LOG_WARNING, 0, @@ -3109,7 +3106,7 @@ gf_ports_reserved (char *blocked_port, gf_boolean_t *ports, uint32_t ceiling) gf_msg_debug ("glusterfs", 0, "lower: %d, higher: %d", tmp_port1, tmp_port2); for (; tmp_port1 <= tmp_port2; tmp_port1++) - ports[tmp_port1] = _gf_true; + BIT_SET (ports, tmp_port1); } out: diff --git a/libglusterfs/src/common-utils.h b/libglusterfs/src/common-utils.h index ccda0d9..9109de9 100644 --- a/libglusterfs/src/common-utils.h +++ b/libglusterfs/src/common-utils.h @@ -98,6 +98,7 @@ void trap (void); #define GF_IANA_PRIV_PORTS_START 49152 /* RFC 6335 */ #define GF_CLNT_INSECURE_PORT_CEILING (GF_IANA_PRIV_PORTS_START - 1) #define GF_PORT_MAX 65535 +#define GF_PORT_ARRAY_SIZE ((GF_PORT_MAX + 7) / 8) #define GF_MINUTE_IN_SECONDS 60 #define GF_HOUR_IN_SECONDS (60*60) @@ -233,6 +234,33 @@ void gf_print_trace (int32_t signal, glusterfs_ctx_t *ctx); int gf_set_log_file_path (cmd_args_t *cmd_args, glusterfs_ctx_t *ctx); int gf_set_log_ident (cmd_args_t *cmd_args); +static inline void +BIT_SET (unsigned char *array, unsigned int index) +{ + unsigned int offset = index / 8; + unsigned int shift = index % 8; + + array[offset] |= (1 << shift); +} + +static inline void +BIT_CLEAR (unsigned char *array, unsigned int index) +{ + unsigned int offset = index / 8; + unsigned int shift = index % 8; + + array[offset] &= ~(1 << shift); +} + +static inline unsigned int +BIT_VALUE (unsigned char *array, unsigned int index) +{ + unsigned int offset = index / 8; + unsigned int shift = index % 8; + + return (array[offset] >> shift) & 0x1; +} + #define VECTORSIZE(count) (count * (sizeof (struct iovec))) #define STRLEN_0(str) (strlen(str) + 1) @@ -769,10 +797,10 @@ uint64_t get_mem_size (); int gf_strip_whitespace (char *str, int len); int gf_canonicalize_path (char *path); char *generate_glusterfs_ctx_id (void); -char *gf_get_reserved_ports(); -int gf_process_reserved_ports (gf_boolean_t ports[], uint32_t ceiling); +char *gf_get_reserved_ports(void); +int gf_process_reserved_ports (unsigned char *ports, uint32_t ceiling); gf_boolean_t -gf_ports_reserved (char *blocked_port, gf_boolean_t *ports, uint32_t ceiling); +gf_ports_reserved (char *blocked_port, unsigned char *ports, uint32_t ceiling); int gf_get_hostname_from_ip (char *client_ip, char **hostname); gf_boolean_t gf_is_local_addr (char *hostname); gf_boolean_t gf_is_same_address (char *host1, char *host2); diff --git a/rpc/rpc-transport/rdma/src/name.c b/rpc/rpc-transport/rdma/src/name.c index 8003b1c..5064427 100644 --- a/rpc/rpc-transport/rdma/src/name.c +++ b/rpc/rpc-transport/rdma/src/name.c @@ -54,10 +54,10 @@ af_inet_bind_to_port_lt_ceiling (struct rdma_cm_id *cm_id, struct sockaddr *sockaddr, socklen_t sockaddr_len, uint32_t ceiling) { - int32_t ret = -1; - uint16_t port = ceiling - 1; - gf_boolean_t ports[GF_PORT_MAX]; - int i = 0; + int32_t ret = -1; + uint16_t port = ceiling - 1; + unsigned char ports[GF_PORT_ARRAY_SIZE] = {0,}; + int i = 0; loop: ret = gf_process_reserved_ports (ports, ceiling); @@ -69,7 +69,7 @@ loop: } /* ignore the reserved ports */ - if (ports[port] == _gf_true) { + if (BIT_VALUE (ports, port)) { port--; continue; } @@ -95,7 +95,7 @@ loop: if (!port) { ceiling = port = GF_CLNT_INSECURE_PORT_CEILING; for (i = 0; i <= ceiling; i++) - ports[i] = _gf_false; + BIT_CLEAR (ports, i); goto loop; } diff --git a/rpc/rpc-transport/socket/src/name.c b/rpc/rpc-transport/socket/src/name.c index 0e34dc2..acd1dc7 100644 --- a/rpc/rpc-transport/socket/src/name.c +++ b/rpc/rpc-transport/socket/src/name.c @@ -42,10 +42,10 @@ static int32_t af_inet_bind_to_port_lt_ceiling (int fd, struct sockaddr *sockaddr, socklen_t sockaddr_len, uint32_t ceiling) { - int32_t ret = -1; - uint16_t port = ceiling - 1; - gf_boolean_t ports[GF_PORT_MAX]; - int i = 0; + int32_t ret = -1; + uint16_t port = ceiling - 1; + unsigned char ports[GF_PORT_ARRAY_SIZE] = {0,}; + int i = 0; loop: ret = gf_process_reserved_ports (ports, ceiling); @@ -57,7 +57,7 @@ loop: } /* ignore the reserved ports */ - if (ports[port] == _gf_true) { + if (BIT_VALUE (ports, port)) { port--; continue; } @@ -83,7 +83,7 @@ loop: if (!port) { ceiling = port = GF_CLNT_INSECURE_PORT_CEILING; for (i = 0; i <= ceiling; i++) - ports[i] = _gf_false; + BIT_CLEAR (ports, i); goto loop; } diff --git a/xlators/performance/io-threads/src/io-threads.h b/xlators/performance/io-threads/src/io-threads.h index fa955b5..2ba2e8e 100644 --- a/xlators/performance/io-threads/src/io-threads.h +++ b/xlators/performance/io-threads/src/io-threads.h @@ -37,7 +37,7 @@ struct iot_conf; #define IOT_MAX_THREADS 64 -#define IOT_THREAD_STACK_SIZE ((size_t)(1024*1024)) +#define IOT_THREAD_STACK_SIZE ((size_t)(256*1024)) typedef enum { -- 1.8.3.1