* [RFC][patch] Make DCACHE_LINE runtime-settable
@ 2011-07-23 2:40 Paul Pluzhnikov
2011-07-23 16:57 ` Eli Zaretskii
` (2 more replies)
0 siblings, 3 replies; 15+ messages in thread
From: Paul Pluzhnikov @ 2011-07-23 2:40 UTC (permalink / raw)
To: gdb-patches; +Cc: ppluzhnikov
Greetings,
Another followup to my earlier "slow on high-latency links" message:
http://sourceware.org/ml/gdb-patches/2011-07/msg00391.html ...
With this change:
2009-08-31 Jacob Potter <jdpotter@google.com>
Doug Evans <dje@google.com>
Implement TARGET_OBJECT_STACK_MEMORY.
* NEWS: Add note on new "set stack-cache" option.
* corefile.c (read_stack): New function.
* dcache.c (dcache_struct): New member ptid.
...
gdb no longer reads stack 4 bytes at a time (good). Instead it reads
LINE_SIZE (== 64) bytes at a time.
With typical x86_64 frame sizes, I see about 1 packet per frame level.
For a 200ms round-trip connection, executing "where" and getting back 30
frames translates into 6 seconds of wall time, and "thread apply all where"
into 1 to 10 to 100 minutes (depending on how many threads there are,
with 100 threads being common and 1000 not being exceptional).
Attached patch allows the user to e.g. "set dcache-line-size 4096" and
drastically reduce the number of round trips.
I've also added "set dcache-size" just for good measure.
Not sure whether this needs documentation updates.
Thanks,
--
Paul Pluzhnikov
2011-07-22 Paul Pluzhnikov <ppluzhnikov@google.com>
* dcache.c (dcache_size): New variable
(dcache_line_size): Likewise.
(struct dcache_block): Make it expandable.
(struct dcache_struct): New field.
(dcache_invalidate): Discard freelist upon dcache_line_size changes.
(dcache_hit, dcache_alloc, dcache_peek_byte): Adjust.
(dcache_poke_byte, dcache_print_line): Adjust.
(set_dcache_size, set_dcache_line_size): New functions.
(_initialize_dcache): Add new commands.
Index: dcache.c
===================================================================
RCS file: /cvs/src/src/gdb/dcache.c,v
retrieving revision 1.45
diff -u -p -r1.45 dcache.c
--- dcache.c 7 Jan 2011 19:36:15 -0000 1.45
+++ dcache.c 22 Jul 2011 21:59:07 -0000
@@ -71,20 +71,21 @@
/* The maximum number of lines stored. The total size of the cache is
equal to DCACHE_SIZE times LINE_SIZE. */
-#define DCACHE_SIZE 4096
+#define DCACHE_DEFAULT_SIZE 4096
+static unsigned dcache_size = DCACHE_DEFAULT_SIZE;
-/* The size of a cache line. Smaller values reduce the time taken to
+/* The default size of a cache line. Smaller values reduce the time taken to
read a single byte and make the cache more granular, but increase
overhead and reduce the effectiveness of the cache as a prefetcher. */
-#define LINE_SIZE_POWER 6
-#define LINE_SIZE (1 << LINE_SIZE_POWER)
+#define DCACHE_DEFAULT_LINE_SIZE 64
+static unsigned dcache_line_size = DCACHE_DEFAULT_LINE_SIZE;
/* Each cache block holds LINE_SIZE bytes of data
starting at a multiple-of-LINE_SIZE address. */
-#define LINE_SIZE_MASK ((LINE_SIZE - 1))
-#define XFORM(x) ((x) & LINE_SIZE_MASK)
-#define MASK(x) ((x) & ~LINE_SIZE_MASK)
+#define LINE_SIZE_MASK(dcache) ((dcache->line_size - 1))
+#define XFORM(dcache, x) ((x) & LINE_SIZE_MASK(dcache))
+#define MASK(dcache, x) ((x) & ~LINE_SIZE_MASK(dcache))
struct dcache_block
{
@@ -93,8 +94,8 @@ struct dcache_block
struct dcache_block *next;
CORE_ADDR addr; /* address of data */
- gdb_byte data[LINE_SIZE]; /* bytes at given address */
int refs; /* # hits */
+ gdb_byte data[0]; /* line_size bytes at given address */
};
struct dcache_struct
@@ -108,6 +109,7 @@ struct dcache_struct
/* The number of in-use lines in the cache. */
int size;
+ CORE_ADDR line_size; /* current line_size. */
/* The ptid of last inferior to use cache or null_ptid. */
ptid_t ptid;
@@ -207,6 +209,29 @@ for_each_block (struct dcache_block **bl
while (*blist && db != *blist);
}
+/* BLOCK_FUNC routine for dcache_free. */
+
+static void
+free_block (struct dcache_block *block, void *param)
+{
+ free (block);
+}
+
+/* Free a data cache. */
+
+void
+dcache_free (DCACHE *dcache)
+{
+ if (last_cache == dcache)
+ last_cache = NULL;
+
+ splay_tree_delete (dcache->tree);
+ for_each_block (&dcache->oldest, free_block, NULL);
+ for_each_block (&dcache->freelist, free_block, NULL);
+ xfree (dcache);
+}
+
+
/* BLOCK_FUNC function for dcache_invalidate.
This doesn't remove the block from the oldest list on purpose.
dcache_invalidate will do it later. */
@@ -230,6 +255,16 @@ dcache_invalidate (DCACHE *dcache)
dcache->oldest = NULL;
dcache->size = 0;
dcache->ptid = null_ptid;
+
+ if (dcache->line_size != dcache_line_size)
+ {
+ /* We've been asked to use a different line size.
+ All of our freelist blocks are now the wrong size, so free them. */
+
+ for_each_block (&dcache->freelist, free_block, dcache);
+ dcache->freelist = NULL;
+ dcache->line_size = dcache_line_size;
+ }
}
/* Invalidate the line associated with ADDR. */
@@ -257,7 +292,7 @@ dcache_hit (DCACHE *dcache, CORE_ADDR ad
struct dcache_block *db;
splay_tree_node node = splay_tree_lookup (dcache->tree,
- (splay_tree_key) MASK (addr));
+ (splay_tree_key) MASK (dcache, addr));
if (!node)
return NULL;
@@ -281,7 +316,7 @@ dcache_read_line (DCACHE *dcache, struct
int reg_len;
struct mem_region *region;
- len = LINE_SIZE;
+ len = dcache->line_size;
memaddr = db->addr;
myaddr = db->data;
@@ -325,7 +360,7 @@ dcache_alloc (DCACHE *dcache, CORE_ADDR
{
struct dcache_block *db;
- if (dcache->size >= DCACHE_SIZE)
+ if (dcache->size >= dcache_size)
{
/* Evict the least recently allocated line. */
db = dcache->oldest;
@@ -339,12 +374,12 @@ dcache_alloc (DCACHE *dcache, CORE_ADDR
if (db)
remove_block (&dcache->freelist, db);
else
- db = xmalloc (sizeof (struct dcache_block));
+ db = xmalloc (sizeof (struct dcache_block) + dcache->line_size);
dcache->size++;
}
- db->addr = MASK (addr);
+ db->addr = MASK (dcache, addr);
db->refs = 0;
/* Put DB at the end of the list, it's the newest. */
@@ -374,7 +409,7 @@ dcache_peek_byte (DCACHE *dcache, CORE_A
return 0;
}
- *ptr = db->data[XFORM (addr)];
+ *ptr = db->data[XFORM (dcache, addr)];
return 1;
}
@@ -395,7 +430,7 @@ dcache_poke_byte (DCACHE *dcache, CORE_A
struct dcache_block *db = dcache_hit (dcache, addr);
if (db)
- db->data[XFORM (addr)] = *ptr;
+ db->data[XFORM (dcache, addr)] = *ptr;
return 1;
}
@@ -427,33 +462,13 @@ dcache_init (void)
dcache->oldest = NULL;
dcache->freelist = NULL;
dcache->size = 0;
+ dcache->line_size = dcache_line_size;
dcache->ptid = null_ptid;
last_cache = dcache;
return dcache;
}
-/* BLOCK_FUNC routine for dcache_free. */
-
-static void
-free_block (struct dcache_block *block, void *param)
-{
- free (block);
-}
-
-/* Free a data cache. */
-
-void
-dcache_free (DCACHE *dcache)
-{
- if (last_cache == dcache)
- last_cache = NULL;
-
- splay_tree_delete (dcache->tree);
- for_each_block (&dcache->oldest, free_block, NULL);
- for_each_block (&dcache->freelist, free_block, NULL);
- xfree (dcache);
-}
/* Read or write LEN bytes from inferior memory at MEMADDR, transferring
to or from debugger address MYADDR. Write to inferior if SHOULD_WRITE is
@@ -571,12 +586,12 @@ dcache_print_line (int index)
printf_filtered (_("Line %d: address %s [%d hits]\n"),
index, paddress (target_gdbarch, db->addr), db->refs);
- for (j = 0; j < LINE_SIZE; j++)
+ for (j = 0; j < last_cache->line_size; j++)
{
printf_filtered ("%02x ", db->data[j]);
/* Print a newline every 16 bytes (48 characters). */
- if ((j % 16 == 15) && (j != LINE_SIZE - 1))
+ if ((j % 16 == 15) && (j != last_cache->line_size - 1))
printf_filtered ("\n");
}
printf_filtered ("\n");
@@ -603,8 +618,10 @@ dcache_info (char *exp, int tty)
return;
}
- printf_filtered (_("Dcache line width %d, maximum size %d\n"),
- LINE_SIZE, DCACHE_SIZE);
+ printf_filtered (_("Dcache %u lines of %u bytes each.\n"),
+ dcache_size,
+ last_cache ? (unsigned) last_cache->line_size
+ : dcache_line_size);
if (!last_cache || ptid_equal (last_cache->ptid, null_ptid))
{
@@ -635,6 +652,35 @@ dcache_info (char *exp, int tty)
printf_filtered (_("Cache state: %d active lines, %d hits\n"), i, refcount);
}
+static void
+set_dcache_size (char *args, int from_tty,
+ struct cmd_list_element *c)
+{
+ if (dcache_size <= 0)
+ {
+ unsigned d = dcache_size;
+ dcache_size = DCACHE_DEFAULT_SIZE;
+ error (_("Invalid dcache size: %u (must be positive)."), d);
+ }
+ if (last_cache)
+ dcache_invalidate (last_cache);
+}
+
+static void
+set_dcache_line_size (char *args, int from_tty,
+ struct cmd_list_element *c)
+{
+ if (dcache_line_size < 2
+ || (dcache_line_size & (dcache_line_size - 1)) != 0)
+ {
+ unsigned d = dcache_line_size;
+ dcache_line_size = DCACHE_DEFAULT_LINE_SIZE;
+ error (_("Invalid dcache line size: %u (must be power of 2)."), d);
+ }
+ if (last_cache)
+ dcache_invalidate (last_cache);
+}
+
void
_initialize_dcache (void)
{
@@ -656,4 +702,21 @@ Print information on the dcache performa
With no arguments, this command prints the cache configuration and a\n\
summary of each line in the cache. Use \"info dcache <lineno> to dump\"\n\
the contents of a given line."));
+
+ add_setshow_uinteger_cmd ("dcache-line-size", class_obscure,
+ &dcache_line_size, _("\
+Set dcache line size (in bytes, must be power of 2)."), _("\
+Show dcache line size."),
+ NULL,
+ set_dcache_line_size,
+ NULL,
+ &setlist, &showlist);
+ add_setshow_uinteger_cmd ("dcache-size", class_obscure,
+ &dcache_size, _("\
+Set number of dcache lines."), _("\
+Show number of dcache lines."),
+ NULL,
+ set_dcache_size,
+ NULL,
+ &setlist, &showlist);
}
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [RFC][patch] Make DCACHE_LINE runtime-settable
2011-07-23 2:40 [RFC][patch] Make DCACHE_LINE runtime-settable Paul Pluzhnikov
@ 2011-07-23 16:57 ` Eli Zaretskii
2011-07-25 15:01 ` Tom Tromey
2011-07-25 19:26 ` Jan Kratochvil
2 siblings, 0 replies; 15+ messages in thread
From: Eli Zaretskii @ 2011-07-23 16:57 UTC (permalink / raw)
To: Paul Pluzhnikov; +Cc: gdb-patches, ppluzhnikov
> Cc: ppluzhnikov@google.com
> Date: Fri, 22 Jul 2011 15:20:25 -0700 (PDT)
> From: ppluzhnikov@google.com (Paul Pluzhnikov)
>
> Attached patch allows the user to e.g. "set dcache-line-size 4096" and
> drastically reduce the number of round trips.
>
> I've also added "set dcache-size" just for good measure.
>
> Not sure whether this needs documentation updates.
It does. Every command and settable option should be documented in
the manual. We also add to NEWS a short notice of each such addition.
Thanks.
> + add_setshow_uinteger_cmd ("dcache-line-size", class_obscure,
> + &dcache_line_size, _("\
> +Set dcache line size (in bytes, must be power of 2)."), _("\
You cannot have a comma in the first line of a command's doc string.
That's because commands that show only that first line, like "help"
and "apropos", will stop at the first comma. See
cli-decode.c:print_doc_line.
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [RFC][patch] Make DCACHE_LINE runtime-settable
2011-07-23 2:40 [RFC][patch] Make DCACHE_LINE runtime-settable Paul Pluzhnikov
2011-07-23 16:57 ` Eli Zaretskii
@ 2011-07-25 15:01 ` Tom Tromey
2011-07-25 18:47 ` Paul Pluzhnikov
2011-07-25 19:26 ` Jan Kratochvil
2 siblings, 1 reply; 15+ messages in thread
From: Tom Tromey @ 2011-07-25 15:01 UTC (permalink / raw)
To: Paul Pluzhnikov; +Cc: gdb-patches
>>>>> "Paul" == Paul Pluzhnikov <ppluzhnikov@google.com> writes:
Paul> Attached patch allows the user to e.g. "set dcache-line-size 4096" and
Paul> drastically reduce the number of round trips.
Paul> I've also added "set dcache-size" just for good measure.
It looks reasonable to me.
Since there is more than one setting starting with "dcache-", how about
adding a new prefix, and renaming to
set dcache size
set dcache line-size
?
Tom
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [RFC][patch] Make DCACHE_LINE runtime-settable
2011-07-25 15:01 ` Tom Tromey
@ 2011-07-25 18:47 ` Paul Pluzhnikov
2011-07-25 19:22 ` Tom Tromey
` (2 more replies)
0 siblings, 3 replies; 15+ messages in thread
From: Paul Pluzhnikov @ 2011-07-25 18:47 UTC (permalink / raw)
To: Tom Tromey; +Cc: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 978 bytes --]
On Mon, Jul 25, 2011 at 7:52 AM, Tom Tromey <tromey@redhat.com> wrote:
> set dcache size
> set dcache line-size
Revised patch attached.
Thanks.
--
Paul Pluzhnikov
2011-07-25 Paul Pluzhnikov <ppluzhnikov@google.com>
* NEWS: Mention dcache configuration.
* dcache.c (dcache_set_list, dcache_show_list): New variables.
(dcache_size, dcache_line_size): New variables.
(struct dcache_block): Make it expandable.
(struct dcache_struct): New field.
(dcache_invalidate): Discard freelist upon dcache_line_size changes.
(dcache_hit, dcache_alloc, dcache_peek_byte): Adjust.
(dcache_poke_byte, dcache_print_line): Adjust.
(set_dcache_size, set_dcache_line_size): New functions.
(set_dcache_command, show_dcache_command): New functions.
(_initialize_dcache): Add new commands.
doc/ChangeLog:
2011-07-25 Paul Pluzhnikov <ppluzhnikov@google.com>
* gdb.texinfo (Caching Remote Data): Document {set,show} dcache
size and line-size.
[-- Attachment #2: gdb-dcache-line-size-20110725.txt --]
[-- Type: text/plain, Size: 11003 bytes --]
Index: NEWS
===================================================================
RCS file: /cvs/src/src/gdb/NEWS,v
retrieving revision 1.444
diff -u -p -r1.444 NEWS
--- NEWS 21 Jul 2011 17:23:55 -0000 1.444
+++ NEWS 25 Jul 2011 18:31:57 -0000
@@ -74,6 +74,8 @@ QTDisable
Dynamically disable a tracepoint in a started trace experiment.
+* Dcache size (number of lines) and line-size are now runtime-configurable.
+
*** Changes in GDB 7.3
* GDB has a new command: "thread find [REGEXP]".
Index: dcache.c
===================================================================
RCS file: /cvs/src/src/gdb/dcache.c,v
retrieving revision 1.45
diff -u -p -r1.45 dcache.c
--- dcache.c 7 Jan 2011 19:36:15 -0000 1.45
+++ dcache.c 25 Jul 2011 18:31:57 -0000
@@ -27,6 +27,10 @@
#include "inferior.h"
#include "splay-tree.h"
+/* Commands with a prefix of `{set,show} dcache'. */
+static struct cmd_list_element *dcache_set_list = NULL;
+static struct cmd_list_element *dcache_show_list = NULL;
+
/* The data cache could lead to incorrect results because it doesn't
know about volatile variables, thus making it impossible to debug
functions which use memory mapped I/O devices. Set the nocache
@@ -71,20 +75,21 @@
/* The maximum number of lines stored. The total size of the cache is
equal to DCACHE_SIZE times LINE_SIZE. */
-#define DCACHE_SIZE 4096
+#define DCACHE_DEFAULT_SIZE 4096
+static unsigned dcache_size = DCACHE_DEFAULT_SIZE;
-/* The size of a cache line. Smaller values reduce the time taken to
+/* The default size of a cache line. Smaller values reduce the time taken to
read a single byte and make the cache more granular, but increase
overhead and reduce the effectiveness of the cache as a prefetcher. */
-#define LINE_SIZE_POWER 6
-#define LINE_SIZE (1 << LINE_SIZE_POWER)
+#define DCACHE_DEFAULT_LINE_SIZE 64
+static unsigned dcache_line_size = DCACHE_DEFAULT_LINE_SIZE;
/* Each cache block holds LINE_SIZE bytes of data
starting at a multiple-of-LINE_SIZE address. */
-#define LINE_SIZE_MASK ((LINE_SIZE - 1))
-#define XFORM(x) ((x) & LINE_SIZE_MASK)
-#define MASK(x) ((x) & ~LINE_SIZE_MASK)
+#define LINE_SIZE_MASK(dcache) ((dcache->line_size - 1))
+#define XFORM(dcache, x) ((x) & LINE_SIZE_MASK(dcache))
+#define MASK(dcache, x) ((x) & ~LINE_SIZE_MASK(dcache))
struct dcache_block
{
@@ -93,8 +98,8 @@ struct dcache_block
struct dcache_block *next;
CORE_ADDR addr; /* address of data */
- gdb_byte data[LINE_SIZE]; /* bytes at given address */
int refs; /* # hits */
+ gdb_byte data[0]; /* line_size bytes at given address */
};
struct dcache_struct
@@ -108,6 +113,7 @@ struct dcache_struct
/* The number of in-use lines in the cache. */
int size;
+ CORE_ADDR line_size; /* current line_size. */
/* The ptid of last inferior to use cache or null_ptid. */
ptid_t ptid;
@@ -207,6 +213,29 @@ for_each_block (struct dcache_block **bl
while (*blist && db != *blist);
}
+/* BLOCK_FUNC routine for dcache_free. */
+
+static void
+free_block (struct dcache_block *block, void *param)
+{
+ free (block);
+}
+
+/* Free a data cache. */
+
+void
+dcache_free (DCACHE *dcache)
+{
+ if (last_cache == dcache)
+ last_cache = NULL;
+
+ splay_tree_delete (dcache->tree);
+ for_each_block (&dcache->oldest, free_block, NULL);
+ for_each_block (&dcache->freelist, free_block, NULL);
+ xfree (dcache);
+}
+
+
/* BLOCK_FUNC function for dcache_invalidate.
This doesn't remove the block from the oldest list on purpose.
dcache_invalidate will do it later. */
@@ -230,6 +259,16 @@ dcache_invalidate (DCACHE *dcache)
dcache->oldest = NULL;
dcache->size = 0;
dcache->ptid = null_ptid;
+
+ if (dcache->line_size != dcache_line_size)
+ {
+ /* We've been asked to use a different line size.
+ All of our freelist blocks are now the wrong size, so free them. */
+
+ for_each_block (&dcache->freelist, free_block, dcache);
+ dcache->freelist = NULL;
+ dcache->line_size = dcache_line_size;
+ }
}
/* Invalidate the line associated with ADDR. */
@@ -257,7 +296,7 @@ dcache_hit (DCACHE *dcache, CORE_ADDR ad
struct dcache_block *db;
splay_tree_node node = splay_tree_lookup (dcache->tree,
- (splay_tree_key) MASK (addr));
+ (splay_tree_key) MASK (dcache, addr));
if (!node)
return NULL;
@@ -281,7 +320,7 @@ dcache_read_line (DCACHE *dcache, struct
int reg_len;
struct mem_region *region;
- len = LINE_SIZE;
+ len = dcache->line_size;
memaddr = db->addr;
myaddr = db->data;
@@ -325,7 +364,7 @@ dcache_alloc (DCACHE *dcache, CORE_ADDR
{
struct dcache_block *db;
- if (dcache->size >= DCACHE_SIZE)
+ if (dcache->size >= dcache_size)
{
/* Evict the least recently allocated line. */
db = dcache->oldest;
@@ -339,12 +378,12 @@ dcache_alloc (DCACHE *dcache, CORE_ADDR
if (db)
remove_block (&dcache->freelist, db);
else
- db = xmalloc (sizeof (struct dcache_block));
+ db = xmalloc (sizeof (struct dcache_block) + dcache->line_size);
dcache->size++;
}
- db->addr = MASK (addr);
+ db->addr = MASK (dcache, addr);
db->refs = 0;
/* Put DB at the end of the list, it's the newest. */
@@ -374,7 +413,7 @@ dcache_peek_byte (DCACHE *dcache, CORE_A
return 0;
}
- *ptr = db->data[XFORM (addr)];
+ *ptr = db->data[XFORM (dcache, addr)];
return 1;
}
@@ -395,7 +434,7 @@ dcache_poke_byte (DCACHE *dcache, CORE_A
struct dcache_block *db = dcache_hit (dcache, addr);
if (db)
- db->data[XFORM (addr)] = *ptr;
+ db->data[XFORM (dcache, addr)] = *ptr;
return 1;
}
@@ -427,33 +466,13 @@ dcache_init (void)
dcache->oldest = NULL;
dcache->freelist = NULL;
dcache->size = 0;
+ dcache->line_size = dcache_line_size;
dcache->ptid = null_ptid;
last_cache = dcache;
return dcache;
}
-/* BLOCK_FUNC routine for dcache_free. */
-
-static void
-free_block (struct dcache_block *block, void *param)
-{
- free (block);
-}
-
-/* Free a data cache. */
-
-void
-dcache_free (DCACHE *dcache)
-{
- if (last_cache == dcache)
- last_cache = NULL;
-
- splay_tree_delete (dcache->tree);
- for_each_block (&dcache->oldest, free_block, NULL);
- for_each_block (&dcache->freelist, free_block, NULL);
- xfree (dcache);
-}
/* Read or write LEN bytes from inferior memory at MEMADDR, transferring
to or from debugger address MYADDR. Write to inferior if SHOULD_WRITE is
@@ -571,12 +590,12 @@ dcache_print_line (int index)
printf_filtered (_("Line %d: address %s [%d hits]\n"),
index, paddress (target_gdbarch, db->addr), db->refs);
- for (j = 0; j < LINE_SIZE; j++)
+ for (j = 0; j < last_cache->line_size; j++)
{
printf_filtered ("%02x ", db->data[j]);
/* Print a newline every 16 bytes (48 characters). */
- if ((j % 16 == 15) && (j != LINE_SIZE - 1))
+ if ((j % 16 == 15) && (j != last_cache->line_size - 1))
printf_filtered ("\n");
}
printf_filtered ("\n");
@@ -603,8 +622,10 @@ dcache_info (char *exp, int tty)
return;
}
- printf_filtered (_("Dcache line width %d, maximum size %d\n"),
- LINE_SIZE, DCACHE_SIZE);
+ printf_filtered (_("Dcache %u lines of %u bytes each.\n"),
+ dcache_size,
+ last_cache ? (unsigned) last_cache->line_size
+ : dcache_line_size);
if (!last_cache || ptid_equal (last_cache->ptid, null_ptid))
{
@@ -635,6 +656,49 @@ dcache_info (char *exp, int tty)
printf_filtered (_("Cache state: %d active lines, %d hits\n"), i, refcount);
}
+static void
+set_dcache_size (char *args, int from_tty,
+ struct cmd_list_element *c)
+{
+ if (dcache_size <= 0)
+ {
+ unsigned d = dcache_size;
+ dcache_size = DCACHE_DEFAULT_SIZE;
+ error (_("Invalid dcache size: %u (must be positive)."), d);
+ }
+ if (last_cache)
+ dcache_invalidate (last_cache);
+}
+
+static void
+set_dcache_line_size (char *args, int from_tty,
+ struct cmd_list_element *c)
+{
+ if (dcache_line_size < 2
+ || (dcache_line_size & (dcache_line_size - 1)) != 0)
+ {
+ unsigned d = dcache_line_size;
+ dcache_line_size = DCACHE_DEFAULT_LINE_SIZE;
+ error (_("Invalid dcache line size: %u (must be power of 2)."), d);
+ }
+ if (last_cache)
+ dcache_invalidate (last_cache);
+}
+
+static void
+set_dcache_command (char *arg, int from_tty)
+{
+ printf_unfiltered (
+ "\"set dcache\" must be followed by the name of a subcommand.\n");
+ help_list (dcache_set_list, "set dcache ", -1, gdb_stdout);
+}
+
+static void
+show_dcache_command (char *args, int from_tty)
+{
+ cmd_show_list (dcache_show_list, from_tty, "");
+}
+
void
_initialize_dcache (void)
{
@@ -656,4 +720,28 @@ Print information on the dcache performa
With no arguments, this command prints the cache configuration and a\n\
summary of each line in the cache. Use \"info dcache <lineno> to dump\"\n\
the contents of a given line."));
+
+ add_prefix_cmd ("dcache", class_obscure, set_dcache_command, _("\
+Use this command to set number of lines in dcache and line-size."),
+ &dcache_set_list, "set dcache ", /*allow_unknown*/0, &setlist);
+ add_prefix_cmd ("dcache", class_obscure, show_dcache_command, _("\
+Show dcachesettings."),
+ &dcache_show_list, "show dcache ", /*allow_unknown*/0, &showlist);
+
+ add_setshow_uinteger_cmd ("line-size", class_obscure,
+ &dcache_line_size, _("\
+Set dcache line size in bytes (must be power of 2)."), _("\
+Show dcache line size."),
+ NULL,
+ set_dcache_line_size,
+ NULL,
+ &dcache_set_list, &dcache_show_list);
+ add_setshow_uinteger_cmd ("size", class_obscure,
+ &dcache_size, _("\
+Set number of dcache lines."), _("\
+Show number of dcache lines."),
+ NULL,
+ set_dcache_size,
+ NULL,
+ &dcache_set_list, &dcache_show_list);
}
Index: doc/gdb.texinfo
===================================================================
RCS file: /cvs/src/src/gdb/doc/gdb.texinfo,v
retrieving revision 1.848
diff -u -p -r1.848 gdb.texinfo
--- doc/gdb.texinfo 21 Jul 2011 15:13:29 -0000 1.848
+++ doc/gdb.texinfo 25 Jul 2011 18:31:57 -0000
@@ -9332,6 +9332,28 @@ operation.
If a line number is specified, the contents of that line will be
printed in hex.
+
+@item set dcache size @var{size}
+@cindex dcache size
+@kindex dcache size
+Set maximum number of entries in dcache (dcache depth above).
+
+@item set dcache line-size @var{line-size}
+@cindex dcache line-size
+@kindex dcache line-size
+Set number of bytes each dcache entry caches (dcache width above).
+Must be a power of 2.
+
+@item show dcache size
+@cindex dcache size
+@kindex dcache size
+Show maximum number of dcache entries. See also @ref{Caching Remote Data, info dcache}.
+
+@item show dcache line-size
+@cindex dcache line-size
+@kindex dcache line-size
+Show default size of dcache lines. See also @ref{Caching Remote Data, info dcache}.
+
@end table
@node Searching Memory
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [RFC][patch] Make DCACHE_LINE runtime-settable
2011-07-25 18:47 ` Paul Pluzhnikov
@ 2011-07-25 19:22 ` Tom Tromey
2011-07-25 19:32 ` Pedro Alves
2011-07-25 20:22 ` Eli Zaretskii
2 siblings, 0 replies; 15+ messages in thread
From: Tom Tromey @ 2011-07-25 19:22 UTC (permalink / raw)
To: Paul Pluzhnikov; +Cc: gdb-patches
>>>>> "Paul" == Paul Pluzhnikov <ppluzhnikov@google.com> writes:
Paul> 2011-07-25 Paul Pluzhnikov <ppluzhnikov@google.com>
Paul> * NEWS: Mention dcache configuration.
Paul> * dcache.c (dcache_set_list, dcache_show_list): New variables.
Paul> (dcache_size, dcache_line_size): New variables.
Paul> (struct dcache_block): Make it expandable.
Paul> (struct dcache_struct): New field.
Paul> (dcache_invalidate): Discard freelist upon dcache_line_size changes.
Paul> (dcache_hit, dcache_alloc, dcache_peek_byte): Adjust.
Paul> (dcache_poke_byte, dcache_print_line): Adjust.
Paul> (set_dcache_size, set_dcache_line_size): New functions.
Paul> (set_dcache_command, show_dcache_command): New functions.
Paul> (_initialize_dcache): Add new commands.
Thanks, Paul.
The code bits are ok.
Tom
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [RFC][patch] Make DCACHE_LINE runtime-settable
2011-07-23 2:40 [RFC][patch] Make DCACHE_LINE runtime-settable Paul Pluzhnikov
2011-07-23 16:57 ` Eli Zaretskii
2011-07-25 15:01 ` Tom Tromey
@ 2011-07-25 19:26 ` Jan Kratochvil
2011-07-25 20:58 ` Paul Pluzhnikov
2 siblings, 1 reply; 15+ messages in thread
From: Jan Kratochvil @ 2011-07-25 19:26 UTC (permalink / raw)
To: Paul Pluzhnikov; +Cc: gdb-patches
On Sat, 23 Jul 2011 00:20:25 +0200, Paul Pluzhnikov wrote:
> For a 200ms round-trip connection, executing "where" and getting back 30
> frames translates into 6 seconds of wall time, and "thread apply all where"
> into 1 to 10 to 100 minutes (depending on how many threads there are,
> with 100 threads being common and 1000 not being exceptional).
>
> Attached patch allows the user to e.g. "set dcache-line-size 4096" and
> drastically reduce the number of round trips.
I was tweaking the LINE_SIZE_POWER facing this problem in mail:
https://fedorahosted.org/pipermail/crash-catcher/2010-December/001441.html
I have seen some of the target_read_memory requests are needlessly fragmented
into LINE_SIZE_POWER sized read requests. Have you considered making the
gdbserver protocol read requests size dynamic depending on the caller's
requested read size?
After all I found it is in many cases the fastest to upload the whole core
file as then there are no RTT delays at all but that is offtopic here.
Thanks,
Jan
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [RFC][patch] Make DCACHE_LINE runtime-settable
2011-07-25 18:47 ` Paul Pluzhnikov
2011-07-25 19:22 ` Tom Tromey
@ 2011-07-25 19:32 ` Pedro Alves
2011-07-25 19:33 ` Tom Tromey
2011-07-25 20:22 ` Eli Zaretskii
2 siblings, 1 reply; 15+ messages in thread
From: Pedro Alves @ 2011-07-25 19:32 UTC (permalink / raw)
To: gdb-patches; +Cc: Paul Pluzhnikov, Tom Tromey
Hi Paul,
On Monday 25 July 2011 19:32:51, Paul Pluzhnikov wrote:
>
> -/* The size of a cache line. Smaller values reduce the time taken to
> +/* The default size of a cache line. Smaller values reduce the time taken to
> read a single byte and make the cache more granular, but increase
> overhead and reduce the effectiveness of the cache as a prefetcher. */
> -#define LINE_SIZE_POWER 6
> -#define LINE_SIZE (1 << LINE_SIZE_POWER)
> +#define DCACHE_DEFAULT_LINE_SIZE 64
> +static unsigned dcache_line_size = DCACHE_DEFAULT_LINE_SIZE;
>
> /* Each cache block holds LINE_SIZE bytes of data
> starting at a multiple-of-LINE_SIZE address. */
>
> -#define LINE_SIZE_MASK ((LINE_SIZE - 1))
> -#define XFORM(x) ((x) & LINE_SIZE_MASK)
> -#define MASK(x) ((x) & ~LINE_SIZE_MASK)
> +#define LINE_SIZE_MASK(dcache) ((dcache->line_size - 1))
> +#define XFORM(dcache, x) ((x) & LINE_SIZE_MASK(dcache))
> +#define MASK(dcache, x) ((x) & ~LINE_SIZE_MASK(dcache))
Missing space after LINE_SIZE_MASK and before `('.
>
> struct dcache_block
> {
> @@ -93,8 +98,8 @@ struct dcache_block
> struct dcache_block *next;
>
> CORE_ADDR addr; /* address of data */
> - gdb_byte data[LINE_SIZE]; /* bytes at given address */
> int refs; /* # hits */
> + gdb_byte data[0]; /* line_size bytes at given address */
Arrays of 0 length are not valid C90. Please make that `gdb_byte data[1]'
and adjust allocation accordingly (using offsetof (..., data) instead of
sizeof, or just subtracting 1).
> +/* BLOCK_FUNC routine for dcache_free. */
> +
> +static void
> +free_block (struct dcache_block *block, void *param)
> +{
> + free (block);
xfree.
>
> +static void
> +set_dcache_size (char *args, int from_tty,
> + struct cmd_list_element *c)
> +{
> + if (dcache_size <= 0)
Given:
> +static unsigned dcache_size = DCACHE_DEFAULT_SIZE;
That < 0 can't ever return true.
> + {
> + unsigned d = dcache_size;
> + dcache_size = DCACHE_DEFAULT_SIZE;
> + error (_("Invalid dcache size: %u (must be positive)."), d);
If you meant to support negatives in the setting, is printing the
number as unsigned your intention? I think it'll look confusing?
> + add_setshow_uinteger_cmd ("line-size", class_obscure,
> + &dcache_line_size, _("\
> +Set dcache line size in bytes (must be power of 2)."), _("\
> +Show dcache line size."),
> + NULL,
> + set_dcache_line_size,
> + NULL,
> + &dcache_set_list, &dcache_show_list);
> + add_setshow_uinteger_cmd ("size", class_obscure,
... you've registered the command as ..._uinteger... so it all looks
like the "must be positive" bits are dead, and you just want to
forbit 0.
--
Pedro Alves
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [RFC][patch] Make DCACHE_LINE runtime-settable
2011-07-25 19:32 ` Pedro Alves
@ 2011-07-25 19:33 ` Tom Tromey
2011-07-25 20:49 ` Pedro Alves
0 siblings, 1 reply; 15+ messages in thread
From: Tom Tromey @ 2011-07-25 19:33 UTC (permalink / raw)
To: Pedro Alves; +Cc: gdb-patches, Paul Pluzhnikov
>>>>> "Pedro" == Pedro Alves <pedro@codesourcery.com> writes:
>> +/* BLOCK_FUNC routine for dcache_free. */
>> +
>> +static void
>> +free_block (struct dcache_block *block, void *param)
>> +{
>> + free (block);
Pedro> xfree.
This one is just moving code from one spot to another.
I don't mind it if Paul wants to fix it, but I think as a rule we
shouldn't "review the context" and make patch submitters fix nits which
already appear in the source.
Tom
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [RFC][patch] Make DCACHE_LINE runtime-settable
2011-07-25 18:47 ` Paul Pluzhnikov
2011-07-25 19:22 ` Tom Tromey
2011-07-25 19:32 ` Pedro Alves
@ 2011-07-25 20:22 ` Eli Zaretskii
2011-07-25 21:04 ` Paul Pluzhnikov
2 siblings, 1 reply; 15+ messages in thread
From: Eli Zaretskii @ 2011-07-25 20:22 UTC (permalink / raw)
To: Paul Pluzhnikov; +Cc: tromey, gdb-patches
> From: Paul Pluzhnikov <ppluzhnikov@google.com>
> Date: Mon, 25 Jul 2011 11:32:51 -0700
> Cc: gdb-patches@sourceware.org
>
> +* Dcache size (number of lines) and line-size are now runtime-configurable.
Please mention the names of the new commands.
> +@item set dcache size @var{size}
> +@cindex dcache size
> +@kindex dcache size
@kindex should say "set dcache size", because @kindex entries are
commands. Same in other commands you introduced.
> +@item show dcache size
> +@cindex dcache size
> +@kindex dcache size
It's not useful to have identical index entries pointing to the same
page. Please remove the second instance.
> +Show maximum number of dcache entries. See also @ref{Caching Remote Data, info dcache}.
^^
Two spaces.
> +@cindex dcache line-size
> +@kindex dcache line-size
> +Show default size of dcache lines. See also @ref{Caching Remote Data, info dcache}.
Same here (both the second index entry and whitespace between
sentences).
OK with those changes.
Thanks.
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [RFC][patch] Make DCACHE_LINE runtime-settable
2011-07-25 19:33 ` Tom Tromey
@ 2011-07-25 20:49 ` Pedro Alves
0 siblings, 0 replies; 15+ messages in thread
From: Pedro Alves @ 2011-07-25 20:49 UTC (permalink / raw)
To: Tom Tromey; +Cc: gdb-patches, Paul Pluzhnikov
On Monday 25 July 2011 20:25:42, Tom Tromey wrote:
> >>>>> "Pedro" == Pedro Alves <pedro@codesourcery.com> writes:
>
> >> +/* BLOCK_FUNC routine for dcache_free. */
> >> +
> >> +static void
> >> +free_block (struct dcache_block *block, void *param)
> >> +{
> >> + free (block);
>
> Pedro> xfree.
>
> This one is just moving code from one spot to another.
> I don't mind it if Paul wants to fix it, but I think as a rule we
> shouldn't "review the context" and make patch submitters fix nits which
> already appear in the source.
Yes, agreed. I just hadn't noticed the function was just being moved.
Paul, if you want to fix that one, it's preaproved, either as
preparatory patch, or as followup.
--
Pedro Alves
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [RFC][patch] Make DCACHE_LINE runtime-settable
2011-07-25 19:26 ` Jan Kratochvil
@ 2011-07-25 20:58 ` Paul Pluzhnikov
2011-07-26 2:55 ` Jan Kratochvil
0 siblings, 1 reply; 15+ messages in thread
From: Paul Pluzhnikov @ 2011-07-25 20:58 UTC (permalink / raw)
To: Jan Kratochvil; +Cc: gdb-patches
On Mon, Jul 25, 2011 at 12:00 PM, Jan Kratochvil
<jan.kratochvil@redhat.com> wrote:
> I was tweaking the LINE_SIZE_POWER facing this problem in mail:
> https://fedorahosted.org/pipermail/crash-catcher/2010-December/001441.html
>
> I have seen some of the target_read_memory requests are needlessly fragmented
> into LINE_SIZE_POWER sized read requests. Have you considered making the
> gdbserver protocol read requests size dynamic depending on the caller's
> requested read size?
Uhm. The caller read request size here is 8 bytes (else I didn't
understand what you are suggesting):
#0 dcache_xfer_memory (ops=0xd34ec0, dcache=0xd647a0,
memaddr=140737234392872, myaddr=0x4719b30 "",
len=8, should_write=0) at ../../src/gdb/dcache.c:496
#1 0x00000000005eaba3 in memory_xfer_partial (ops=0xd34ec0,
object=TARGET_OBJECT_STACK_MEMORY,
readbuf=0x4719b30,
writebuf=0x0,
memaddr=140737234392872,
len=8) at
../../src/gdb/target.c:1522
#2 0x00000000005eae72 in target_xfer_partial (ops=0xd34ec0,
object=TARGET_OBJECT_STACK_MEMORY,
annex=0x0, readbuf=0x4719b30,
writebuf=0x0,
offset=140737234392872, len=8)
at ../../src/gdb/target.c:1625
#3 0x00000000005eb6cc in target_read_partial (ops=0xd34ec0,
object=TARGET_OBJECT_STACK_MEMORY,
annex=0x0, buf=0x4719b30 "",
offset=140737234392872, len=8)
at ../../src/gdb/target.c:1904
#4 0x00000000005eb796 in target_read (ops=0xd34ec0,
object=TARGET_OBJECT_STACK_MEMORY,
annex=0x0, buf=0x4719b30 "",
offset=140737234392872, len=8)
at ../../src/gdb/target.c:1930
#5 0x00000000005eb121 in target_read_stack (memaddr=140737234392872,
myaddr=0x4719b30 "", len=8)
at ../../src/gdb/target.c:1719
#6 0x0000000000475c21 in read_stack (memaddr=140737234392872,
myaddr=0x4719b30 "", len=8) at
../../src/gdb/corefile.c:252
#7 0x000000000057392b in read_value_memory (val=0x8f52b20,
embedded_offset=0, stack=1,
memaddr=140737234392872,
buffer=0x4719b30 "", length=8)
at ../../src/gdb/valops.c:1135
#8 0x000000000057335a in value_fetch_lazy (val=0x8f52b20)
at ../../src/gdb/valops.c:1018
#9 0x0000000000564975 in value_contents_for_printing (value=0x8f52b20)
at ../../src/gdb/value.c:842
#10 0x000000000057e747 in common_val_print (val=0x8f52b20,
stream=0x10792f0, recurse=2,
options=0x7fffffffcaa0,
language=0x950500) at
../../src/gdb/valprint.c:454
#11 0x00000000005bb765 in print_frame_args (func=0x6ec32e0, frame=0x621f6b0,
num=-1, stream=0xfac4e0)
at ../../src/gdb/stack.c:381
#12 0x00000000005bb914 in print_args_stub (args=0x7fffffffcd00)
at ../../src/gdb/stack.c:434
#13 0x00000000005c30ff in catch_errors (func=0x5bb863
<print_args_stub>, func_args=0x7fffffffcd00, errstring=0x921f08 "",
mask=2) at ../../src/gdb/exceptions.c:506
#14 0x00000000005bc56f in print_frame (frame=0x621f6b0, print_level=1,
print_what=LOCATION, print_args=1, sal=...) at
../../src/gdb/stack.c:828
#15 0x00000000005bbdd4 in print_frame_info (frame=0x621f6b0,
print_level=1, print_what=LOCATION, print_args=1) at
../../src/gdb/stack.c:599
#16 0x00000000005bd9bc in backtrace_command_1 (count_exp=0x0,
show_locals=0, from_tty=0) at ../../src/gdb/stack.c:1382
#17 0x00000000005bdab8 in backtrace_command_stub (data=0x7fffffffcfc0)
at ../../src/gdb/stack.c:1421
...
> After all I found it is in many cases the fastest to upload the whole core
> file as then there are no RTT delays at all but that is offtopic here.
This is live server debugging. Also, taking full core is often impractical,
as the RSS exceeds 20GB.
--
Paul Pluzhnikov
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [RFC][patch] Make DCACHE_LINE runtime-settable
2011-07-25 20:22 ` Eli Zaretskii
@ 2011-07-25 21:04 ` Paul Pluzhnikov
2011-07-26 0:28 ` Pedro Alves
2011-07-26 9:51 ` Eli Zaretskii
0 siblings, 2 replies; 15+ messages in thread
From: Paul Pluzhnikov @ 2011-07-25 21:04 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: tromey, gdb-patches, Pedro Alves
[-- Attachment #1: Type: text/plain, Size: 1115 bytes --]
On Mon, Jul 25, 2011 at 12:32 PM, Eli Zaretskii <eliz@gnu.org> wrote:
>> +* Dcache size (number of lines) and line-size are now runtime-configurable.
>
> Please mention the names of the new commands.
Revised patch to address documentation and code comments attached.
Thanks,
--
Paul Pluzhnikov
2011-07-25 Paul Pluzhnikov <ppluzhnikov@google.com>
* NEWS: Mention dcache configuration.
* dcache.c (dcache_set_list, dcache_show_list): New variables.
(dcache_size, dcache_line_size): New variables.
(LINE_SIZE_MASK, XFORM, MASK): Adjust.
(struct dcache_block): Make it expandable.
(struct dcache_struct): New field.
(dcache_invalidate): Discard freelist upon dcache_line_size changes.
(dcache_hit, dcache_alloc, dcache_peek_byte): Adjust.
(dcache_poke_byte, dcache_print_line): Adjust.
(set_dcache_size, set_dcache_line_size): New functions.
(set_dcache_command, show_dcache_command): New functions.
(_initialize_dcache): Add new commands.
doc/ChangeLog:
2011-07-25 Paul Pluzhnikov <ppluzhnikov@google.com>
* gdb.texinfo (Caching Remote Data): Document {set,show} dcache
size and line-size.
[-- Attachment #2: gdb-dcache-line-size-20110725-2.txt --]
[-- Type: text/plain, Size: 11046 bytes --]
Index: NEWS
===================================================================
RCS file: /cvs/src/src/gdb/NEWS,v
retrieving revision 1.444
diff -u -p -r1.444 NEWS
--- NEWS 21 Jul 2011 17:23:55 -0000 1.444
+++ NEWS 25 Jul 2011 20:43:38 -0000
@@ -74,6 +74,9 @@ QTDisable
Dynamically disable a tracepoint in a started trace experiment.
+* Dcache size (number of lines) and line-size are now runtime-configurable
+ via "set dcache line" and "set dcache line-size" commands.
+
*** Changes in GDB 7.3
* GDB has a new command: "thread find [REGEXP]".
Index: dcache.c
===================================================================
RCS file: /cvs/src/src/gdb/dcache.c,v
retrieving revision 1.45
diff -u -p -r1.45 dcache.c
--- dcache.c 7 Jan 2011 19:36:15 -0000 1.45
+++ dcache.c 25 Jul 2011 20:43:38 -0000
@@ -27,6 +27,10 @@
#include "inferior.h"
#include "splay-tree.h"
+/* Commands with a prefix of `{set,show} dcache'. */
+static struct cmd_list_element *dcache_set_list = NULL;
+static struct cmd_list_element *dcache_show_list = NULL;
+
/* The data cache could lead to incorrect results because it doesn't
know about volatile variables, thus making it impossible to debug
functions which use memory mapped I/O devices. Set the nocache
@@ -71,20 +75,21 @@
/* The maximum number of lines stored. The total size of the cache is
equal to DCACHE_SIZE times LINE_SIZE. */
-#define DCACHE_SIZE 4096
+#define DCACHE_DEFAULT_SIZE 4096
+static unsigned dcache_size = DCACHE_DEFAULT_SIZE;
-/* The size of a cache line. Smaller values reduce the time taken to
+/* The default size of a cache line. Smaller values reduce the time taken to
read a single byte and make the cache more granular, but increase
overhead and reduce the effectiveness of the cache as a prefetcher. */
-#define LINE_SIZE_POWER 6
-#define LINE_SIZE (1 << LINE_SIZE_POWER)
+#define DCACHE_DEFAULT_LINE_SIZE 64
+static unsigned dcache_line_size = DCACHE_DEFAULT_LINE_SIZE;
/* Each cache block holds LINE_SIZE bytes of data
starting at a multiple-of-LINE_SIZE address. */
-#define LINE_SIZE_MASK ((LINE_SIZE - 1))
-#define XFORM(x) ((x) & LINE_SIZE_MASK)
-#define MASK(x) ((x) & ~LINE_SIZE_MASK)
+#define LINE_SIZE_MASK(dcache) ((dcache->line_size - 1))
+#define XFORM(dcache, x) ((x) & LINE_SIZE_MASK (dcache))
+#define MASK(dcache, x) ((x) & ~LINE_SIZE_MASK (dcache))
struct dcache_block
{
@@ -93,8 +98,8 @@ struct dcache_block
struct dcache_block *next;
CORE_ADDR addr; /* address of data */
- gdb_byte data[LINE_SIZE]; /* bytes at given address */
int refs; /* # hits */
+ gdb_byte data[1]; /* line_size bytes at given address */
};
struct dcache_struct
@@ -108,6 +113,7 @@ struct dcache_struct
/* The number of in-use lines in the cache. */
int size;
+ CORE_ADDR line_size; /* current line_size. */
/* The ptid of last inferior to use cache or null_ptid. */
ptid_t ptid;
@@ -207,6 +213,29 @@ for_each_block (struct dcache_block **bl
while (*blist && db != *blist);
}
+/* BLOCK_FUNC routine for dcache_free. */
+
+static void
+free_block (struct dcache_block *block, void *param)
+{
+ xfree (block);
+}
+
+/* Free a data cache. */
+
+void
+dcache_free (DCACHE *dcache)
+{
+ if (last_cache == dcache)
+ last_cache = NULL;
+
+ splay_tree_delete (dcache->tree);
+ for_each_block (&dcache->oldest, free_block, NULL);
+ for_each_block (&dcache->freelist, free_block, NULL);
+ xfree (dcache);
+}
+
+
/* BLOCK_FUNC function for dcache_invalidate.
This doesn't remove the block from the oldest list on purpose.
dcache_invalidate will do it later. */
@@ -230,6 +259,16 @@ dcache_invalidate (DCACHE *dcache)
dcache->oldest = NULL;
dcache->size = 0;
dcache->ptid = null_ptid;
+
+ if (dcache->line_size != dcache_line_size)
+ {
+ /* We've been asked to use a different line size.
+ All of our freelist blocks are now the wrong size, so free them. */
+
+ for_each_block (&dcache->freelist, free_block, dcache);
+ dcache->freelist = NULL;
+ dcache->line_size = dcache_line_size;
+ }
}
/* Invalidate the line associated with ADDR. */
@@ -257,7 +296,7 @@ dcache_hit (DCACHE *dcache, CORE_ADDR ad
struct dcache_block *db;
splay_tree_node node = splay_tree_lookup (dcache->tree,
- (splay_tree_key) MASK (addr));
+ (splay_tree_key) MASK (dcache, addr));
if (!node)
return NULL;
@@ -281,7 +320,7 @@ dcache_read_line (DCACHE *dcache, struct
int reg_len;
struct mem_region *region;
- len = LINE_SIZE;
+ len = dcache->line_size;
memaddr = db->addr;
myaddr = db->data;
@@ -325,7 +364,7 @@ dcache_alloc (DCACHE *dcache, CORE_ADDR
{
struct dcache_block *db;
- if (dcache->size >= DCACHE_SIZE)
+ if (dcache->size >= dcache_size)
{
/* Evict the least recently allocated line. */
db = dcache->oldest;
@@ -339,12 +378,13 @@ dcache_alloc (DCACHE *dcache, CORE_ADDR
if (db)
remove_block (&dcache->freelist, db);
else
- db = xmalloc (sizeof (struct dcache_block));
+ db = xmalloc (offsetof (struct dcache_block, data) +
+ dcache->line_size);
dcache->size++;
}
- db->addr = MASK (addr);
+ db->addr = MASK (dcache, addr);
db->refs = 0;
/* Put DB at the end of the list, it's the newest. */
@@ -374,7 +414,7 @@ dcache_peek_byte (DCACHE *dcache, CORE_A
return 0;
}
- *ptr = db->data[XFORM (addr)];
+ *ptr = db->data[XFORM (dcache, addr)];
return 1;
}
@@ -395,7 +435,7 @@ dcache_poke_byte (DCACHE *dcache, CORE_A
struct dcache_block *db = dcache_hit (dcache, addr);
if (db)
- db->data[XFORM (addr)] = *ptr;
+ db->data[XFORM (dcache, addr)] = *ptr;
return 1;
}
@@ -427,33 +467,13 @@ dcache_init (void)
dcache->oldest = NULL;
dcache->freelist = NULL;
dcache->size = 0;
+ dcache->line_size = dcache_line_size;
dcache->ptid = null_ptid;
last_cache = dcache;
return dcache;
}
-/* BLOCK_FUNC routine for dcache_free. */
-
-static void
-free_block (struct dcache_block *block, void *param)
-{
- free (block);
-}
-
-/* Free a data cache. */
-
-void
-dcache_free (DCACHE *dcache)
-{
- if (last_cache == dcache)
- last_cache = NULL;
-
- splay_tree_delete (dcache->tree);
- for_each_block (&dcache->oldest, free_block, NULL);
- for_each_block (&dcache->freelist, free_block, NULL);
- xfree (dcache);
-}
/* Read or write LEN bytes from inferior memory at MEMADDR, transferring
to or from debugger address MYADDR. Write to inferior if SHOULD_WRITE is
@@ -571,12 +591,12 @@ dcache_print_line (int index)
printf_filtered (_("Line %d: address %s [%d hits]\n"),
index, paddress (target_gdbarch, db->addr), db->refs);
- for (j = 0; j < LINE_SIZE; j++)
+ for (j = 0; j < last_cache->line_size; j++)
{
printf_filtered ("%02x ", db->data[j]);
/* Print a newline every 16 bytes (48 characters). */
- if ((j % 16 == 15) && (j != LINE_SIZE - 1))
+ if ((j % 16 == 15) && (j != last_cache->line_size - 1))
printf_filtered ("\n");
}
printf_filtered ("\n");
@@ -603,8 +623,10 @@ dcache_info (char *exp, int tty)
return;
}
- printf_filtered (_("Dcache line width %d, maximum size %d\n"),
- LINE_SIZE, DCACHE_SIZE);
+ printf_filtered (_("Dcache %u lines of %u bytes each.\n"),
+ dcache_size,
+ last_cache ? (unsigned) last_cache->line_size
+ : dcache_line_size);
if (!last_cache || ptid_equal (last_cache->ptid, null_ptid))
{
@@ -635,6 +657,49 @@ dcache_info (char *exp, int tty)
printf_filtered (_("Cache state: %d active lines, %d hits\n"), i, refcount);
}
+static void
+set_dcache_size (char *args, int from_tty,
+ struct cmd_list_element *c)
+{
+ if (dcache_size == 0)
+ {
+ unsigned d = dcache_size;
+ dcache_size = DCACHE_DEFAULT_SIZE;
+ error (_("Dcache size must be greater than 0."));
+ }
+ if (last_cache)
+ dcache_invalidate (last_cache);
+}
+
+static void
+set_dcache_line_size (char *args, int from_tty,
+ struct cmd_list_element *c)
+{
+ if (dcache_line_size < 2
+ || (dcache_line_size & (dcache_line_size - 1)) != 0)
+ {
+ unsigned d = dcache_line_size;
+ dcache_line_size = DCACHE_DEFAULT_LINE_SIZE;
+ error (_("Invalid dcache line size: %u (must be power of 2)."), d);
+ }
+ if (last_cache)
+ dcache_invalidate (last_cache);
+}
+
+static void
+set_dcache_command (char *arg, int from_tty)
+{
+ printf_unfiltered (
+ "\"set dcache\" must be followed by the name of a subcommand.\n");
+ help_list (dcache_set_list, "set dcache ", -1, gdb_stdout);
+}
+
+static void
+show_dcache_command (char *args, int from_tty)
+{
+ cmd_show_list (dcache_show_list, from_tty, "");
+}
+
void
_initialize_dcache (void)
{
@@ -656,4 +721,28 @@ Print information on the dcache performa
With no arguments, this command prints the cache configuration and a\n\
summary of each line in the cache. Use \"info dcache <lineno> to dump\"\n\
the contents of a given line."));
+
+ add_prefix_cmd ("dcache", class_obscure, set_dcache_command, _("\
+Use this command to set number of lines in dcache and line-size."),
+ &dcache_set_list, "set dcache ", /*allow_unknown*/0, &setlist);
+ add_prefix_cmd ("dcache", class_obscure, show_dcache_command, _("\
+Show dcachesettings."),
+ &dcache_show_list, "show dcache ", /*allow_unknown*/0, &showlist);
+
+ add_setshow_uinteger_cmd ("line-size", class_obscure,
+ &dcache_line_size, _("\
+Set dcache line size in bytes (must be power of 2)."), _("\
+Show dcache line size."),
+ NULL,
+ set_dcache_line_size,
+ NULL,
+ &dcache_set_list, &dcache_show_list);
+ add_setshow_uinteger_cmd ("size", class_obscure,
+ &dcache_size, _("\
+Set number of dcache lines."), _("\
+Show number of dcache lines."),
+ NULL,
+ set_dcache_size,
+ NULL,
+ &dcache_set_list, &dcache_show_list);
}
Index: doc/gdb.texinfo
===================================================================
RCS file: /cvs/src/src/gdb/doc/gdb.texinfo,v
retrieving revision 1.848
diff -u -p -r1.848 gdb.texinfo
--- doc/gdb.texinfo 21 Jul 2011 15:13:29 -0000 1.848
+++ doc/gdb.texinfo 25 Jul 2011 20:43:39 -0000
@@ -9332,6 +9332,26 @@ operation.
If a line number is specified, the contents of that line will be
printed in hex.
+
+@item set dcache size @var{size}
+@cindex dcache size
+@kindex set dcache size
+Set maximum number of entries in dcache (dcache depth above).
+
+@item set dcache line-size @var{line-size}
+@cindex dcache line-size
+@kindex set dcache line-size
+Set number of bytes each dcache entry caches (dcache width above).
+Must be a power of 2.
+
+@item show dcache size
+@kindex show dcache size
+Show maximum number of dcache entries. See also @ref{Caching Remote Data, info dcache}.
+
+@item show dcache line-size
+@kindex show dcache line-size
+Show default size of dcache lines. See also @ref{Caching Remote Data, info dcache}.
+
@end table
@node Searching Memory
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [RFC][patch] Make DCACHE_LINE runtime-settable
2011-07-25 21:04 ` Paul Pluzhnikov
@ 2011-07-26 0:28 ` Pedro Alves
2011-07-26 9:51 ` Eli Zaretskii
1 sibling, 0 replies; 15+ messages in thread
From: Pedro Alves @ 2011-07-26 0:28 UTC (permalink / raw)
To: Paul Pluzhnikov; +Cc: Eli Zaretskii, tromey, gdb-patches
This version is fine with me. Thank you.
--
Pedro Alves
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [RFC][patch] Make DCACHE_LINE runtime-settable
2011-07-25 20:58 ` Paul Pluzhnikov
@ 2011-07-26 2:55 ` Jan Kratochvil
0 siblings, 0 replies; 15+ messages in thread
From: Jan Kratochvil @ 2011-07-26 2:55 UTC (permalink / raw)
To: Paul Pluzhnikov; +Cc: gdb-patches
On Mon, 25 Jul 2011 22:21:18 +0200, Paul Pluzhnikov wrote:
> On Mon, Jul 25, 2011 at 12:00 PM, Jan Kratochvil <jan.kratochvil@redhat.com> wrote:
> > I have seen some of the target_read_memory requests are needlessly fragmented
> > into LINE_SIZE_POWER sized read requests. Â Have you considered making the
> > gdbserver protocol read requests size dynamic depending on the caller's
> > requested read size?
>
> Uhm. The caller read request size here is 8 bytes (else I didn't
> understand what you are suggesting):
I was rechecking now the problem of consecutive small reads:
Sending packet: $m152bfc0,4#c0...Packet received: 2f757372
Sending packet: $m152bfc4,4#c4...Packet received: 2f6c6962
Sending packet: $m152bfc8,4#c8...Packet received: 36342f72
Sending packet: $m152bfcc,4#f3...Packet received: 65646c61
and they come from target_read_string - which you already solve in the other
thread. I had wrong expectation they come from large memory transfer
requests.
Thanks,
Jan
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [RFC][patch] Make DCACHE_LINE runtime-settable
2011-07-25 21:04 ` Paul Pluzhnikov
2011-07-26 0:28 ` Pedro Alves
@ 2011-07-26 9:51 ` Eli Zaretskii
1 sibling, 0 replies; 15+ messages in thread
From: Eli Zaretskii @ 2011-07-26 9:51 UTC (permalink / raw)
To: Paul Pluzhnikov; +Cc: tromey, gdb-patches, pedro
> From: Paul Pluzhnikov <ppluzhnikov@google.com>
> Date: Mon, 25 Jul 2011 13:49:02 -0700
> Cc: tromey@redhat.com, gdb-patches@sourceware.org, Pedro Alves <pedro@codesourcery.com>
>
> On Mon, Jul 25, 2011 at 12:32 PM, Eli Zaretskii <eliz@gnu.org> wrote:
>
> >> +* Dcache size (number of lines) and line-size are now runtime-configurable.
> >
> > Please mention the names of the new commands.
>
> Revised patch to address documentation and code comments attached.
OK, thanks.
^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2011-07-26 2:58 UTC | newest]
Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-07-23 2:40 [RFC][patch] Make DCACHE_LINE runtime-settable Paul Pluzhnikov
2011-07-23 16:57 ` Eli Zaretskii
2011-07-25 15:01 ` Tom Tromey
2011-07-25 18:47 ` Paul Pluzhnikov
2011-07-25 19:22 ` Tom Tromey
2011-07-25 19:32 ` Pedro Alves
2011-07-25 19:33 ` Tom Tromey
2011-07-25 20:49 ` Pedro Alves
2011-07-25 20:22 ` Eli Zaretskii
2011-07-25 21:04 ` Paul Pluzhnikov
2011-07-26 0:28 ` Pedro Alves
2011-07-26 9:51 ` Eli Zaretskii
2011-07-25 19:26 ` Jan Kratochvil
2011-07-25 20:58 ` Paul Pluzhnikov
2011-07-26 2:55 ` Jan Kratochvil
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox