diff options
| author | Jiri Olsa <jolsa@kernel.org> | 2014-05-07 15:09:59 -0400 |
|---|---|---|
| committer | Jiri Olsa <jolsa@kernel.org> | 2014-06-12 10:53:22 -0400 |
| commit | c1f9aa0a61bde512a68060883d1c3c1955a546ea (patch) | |
| tree | 5cdd3b3e9bcb18b779ffebad8e23d7540a15ec0b | |
| parent | a08cae03f430b971afa508a32662dc476d42d8cb (diff) | |
perf tools: Add dso__data_* interface descriptons
Adding descriptions/explanations for dso__data_* interface
functions.
Acked-by: Namhyung Kim <namhyung@kernel.org>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jean Pihet <jean.pihet@linaro.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/1401892622-30848-10-git-send-email-jolsa@kernel.org
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
| -rw-r--r-- | tools/perf/util/dso.c | 59 | ||||
| -rw-r--r-- | tools/perf/util/dso.h | 38 |
2 files changed, 97 insertions, 0 deletions
diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c index c30752c7eebb..819f10414f08 100644 --- a/tools/perf/util/dso.c +++ b/tools/perf/util/dso.c | |||
| @@ -205,6 +205,13 @@ static int __open_dso(struct dso *dso, struct machine *machine) | |||
| 205 | 205 | ||
| 206 | static void check_data_close(void); | 206 | static void check_data_close(void); |
| 207 | 207 | ||
| 208 | /** | ||
| 209 | * dso_close - Open DSO data file | ||
| 210 | * @dso: dso object | ||
| 211 | * | ||
| 212 | * Open @dso's data file descriptor and updates | ||
| 213 | * list/count of open DSO objects. | ||
| 214 | */ | ||
| 208 | static int open_dso(struct dso *dso, struct machine *machine) | 215 | static int open_dso(struct dso *dso, struct machine *machine) |
| 209 | { | 216 | { |
| 210 | int fd = __open_dso(dso, machine); | 217 | int fd = __open_dso(dso, machine); |
| @@ -231,6 +238,13 @@ static void close_data_fd(struct dso *dso) | |||
| 231 | } | 238 | } |
| 232 | } | 239 | } |
| 233 | 240 | ||
| 241 | /** | ||
| 242 | * dso_close - Close DSO data file | ||
| 243 | * @dso: dso object | ||
| 244 | * | ||
| 245 | * Close @dso's data file descriptor and updates | ||
| 246 | * list/count of open DSO objects. | ||
| 247 | */ | ||
| 234 | static void close_dso(struct dso *dso) | 248 | static void close_dso(struct dso *dso) |
| 235 | { | 249 | { |
| 236 | close_data_fd(dso); | 250 | close_data_fd(dso); |
| @@ -276,6 +290,11 @@ static bool may_cache_fd(void) | |||
| 276 | return limit > (rlim_t) dso__data_open_cnt; | 290 | return limit > (rlim_t) dso__data_open_cnt; |
| 277 | } | 291 | } |
| 278 | 292 | ||
| 293 | /* | ||
| 294 | * Check and close LRU dso if we crossed allowed limit | ||
| 295 | * for opened dso file descriptors. The limit is half | ||
| 296 | * of the RLIMIT_NOFILE files opened. | ||
| 297 | */ | ||
| 279 | static void check_data_close(void) | 298 | static void check_data_close(void) |
| 280 | { | 299 | { |
| 281 | bool cache_fd = may_cache_fd(); | 300 | bool cache_fd = may_cache_fd(); |
| @@ -284,11 +303,25 @@ static void check_data_close(void) | |||
| 284 | close_first_dso(); | 303 | close_first_dso(); |
| 285 | } | 304 | } |
| 286 | 305 | ||
| 306 | /** | ||
| 307 | * dso__data_close - Close DSO data file | ||
| 308 | * @dso: dso object | ||
| 309 | * | ||
| 310 | * External interface to close @dso's data file descriptor. | ||
| 311 | */ | ||
| 287 | void dso__data_close(struct dso *dso) | 312 | void dso__data_close(struct dso *dso) |
| 288 | { | 313 | { |
| 289 | close_dso(dso); | 314 | close_dso(dso); |
| 290 | } | 315 | } |
| 291 | 316 | ||
| 317 | /** | ||
| 318 | * dso__data_fd - Get dso's data file descriptor | ||
| 319 | * @dso: dso object | ||
| 320 | * @machine: machine object | ||
| 321 | * | ||
| 322 | * External interface to find dso's file, open it and | ||
| 323 | * returns file descriptor. | ||
| 324 | */ | ||
| 292 | int dso__data_fd(struct dso *dso, struct machine *machine) | 325 | int dso__data_fd(struct dso *dso, struct machine *machine) |
| 293 | { | 326 | { |
| 294 | enum dso_binary_type binary_type_data[] = { | 327 | enum dso_binary_type binary_type_data[] = { |
| @@ -445,6 +478,11 @@ static ssize_t dso_cache_read(struct dso *dso, u64 offset, | |||
| 445 | return dso_cache__read(dso, offset, data, size); | 478 | return dso_cache__read(dso, offset, data, size); |
| 446 | } | 479 | } |
| 447 | 480 | ||
| 481 | /* | ||
| 482 | * Reads and caches dso data DSO__DATA_CACHE_SIZE size chunks | ||
| 483 | * in the rb_tree. Any read to already cached data is served | ||
| 484 | * by cached data. | ||
| 485 | */ | ||
| 448 | static ssize_t cached_read(struct dso *dso, u64 offset, u8 *data, ssize_t size) | 486 | static ssize_t cached_read(struct dso *dso, u64 offset, u8 *data, ssize_t size) |
| 449 | { | 487 | { |
| 450 | ssize_t r = 0; | 488 | ssize_t r = 0; |
| @@ -504,6 +542,17 @@ static ssize_t data_read_offset(struct dso *dso, u64 offset, | |||
| 504 | return cached_read(dso, offset, data, size); | 542 | return cached_read(dso, offset, data, size); |
| 505 | } | 543 | } |
| 506 | 544 | ||
| 545 | /** | ||
| 546 | * dso__data_read_offset - Read data from dso file offset | ||
| 547 | * @dso: dso object | ||
| 548 | * @machine: machine object | ||
| 549 | * @offset: file offset | ||
| 550 | * @data: buffer to store data | ||
| 551 | * @size: size of the @data buffer | ||
| 552 | * | ||
| 553 | * External interface to read data from dso file offset. Open | ||
| 554 | * dso data file and use cached_read to get the data. | ||
| 555 | */ | ||
| 507 | ssize_t dso__data_read_offset(struct dso *dso, struct machine *machine, | 556 | ssize_t dso__data_read_offset(struct dso *dso, struct machine *machine, |
| 508 | u64 offset, u8 *data, ssize_t size) | 557 | u64 offset, u8 *data, ssize_t size) |
| 509 | { | 558 | { |
| @@ -513,6 +562,16 @@ ssize_t dso__data_read_offset(struct dso *dso, struct machine *machine, | |||
| 513 | return data_read_offset(dso, offset, data, size); | 562 | return data_read_offset(dso, offset, data, size); |
| 514 | } | 563 | } |
| 515 | 564 | ||
| 565 | /** | ||
| 566 | * dso__data_read_addr - Read data from dso address | ||
| 567 | * @dso: dso object | ||
| 568 | * @machine: machine object | ||
| 569 | * @add: virtual memory address | ||
| 570 | * @data: buffer to store data | ||
| 571 | * @size: size of the @data buffer | ||
| 572 | * | ||
| 573 | * External interface to read data from dso address. | ||
| 574 | */ | ||
| 516 | ssize_t dso__data_read_addr(struct dso *dso, struct map *map, | 575 | ssize_t dso__data_read_addr(struct dso *dso, struct map *map, |
| 517 | struct machine *machine, u64 addr, | 576 | struct machine *machine, u64 addr, |
| 518 | u8 *data, ssize_t size) | 577 | u8 *data, ssize_t size) |
diff --git a/tools/perf/util/dso.h b/tools/perf/util/dso.h index da47b13595f3..ad553ba257bf 100644 --- a/tools/perf/util/dso.h +++ b/tools/perf/util/dso.h | |||
| @@ -149,6 +149,44 @@ char dso__symtab_origin(const struct dso *dso); | |||
| 149 | int dso__read_binary_type_filename(const struct dso *dso, enum dso_binary_type type, | 149 | int dso__read_binary_type_filename(const struct dso *dso, enum dso_binary_type type, |
| 150 | char *root_dir, char *filename, size_t size); | 150 | char *root_dir, char *filename, size_t size); |
| 151 | 151 | ||
| 152 | /* | ||
| 153 | * The dso__data_* external interface provides following functions: | ||
| 154 | * dso__data_fd | ||
| 155 | * dso__data_close | ||
| 156 | * dso__data_read_offset | ||
| 157 | * dso__data_read_addr | ||
| 158 | * | ||
| 159 | * Please refer to the dso.c object code for each function and | ||
| 160 | * arguments documentation. Following text tries to explain the | ||
| 161 | * dso file descriptor caching. | ||
| 162 | * | ||
| 163 | * The dso__data* interface allows caching of opened file descriptors | ||
| 164 | * to speed up the dso data accesses. The idea is to leave the file | ||
| 165 | * descriptor opened ideally for the whole life of the dso object. | ||
| 166 | * | ||
| 167 | * The current usage of the dso__data_* interface is as follows: | ||
| 168 | * | ||
| 169 | * Get DSO's fd: | ||
| 170 | * int fd = dso__data_fd(dso, machine); | ||
| 171 | * USE 'fd' SOMEHOW | ||
| 172 | * | ||
| 173 | * Read DSO's data: | ||
| 174 | * n = dso__data_read_offset(dso_0, &machine, 0, buf, BUFSIZE); | ||
| 175 | * n = dso__data_read_addr(dso_0, &machine, 0, buf, BUFSIZE); | ||
| 176 | * | ||
| 177 | * Eventually close DSO's fd: | ||
| 178 | * dso__data_close(dso); | ||
| 179 | * | ||
| 180 | * It is not necessary to close the DSO object data file. Each time new | ||
| 181 | * DSO data file is opened, the limit (RLIMIT_NOFILE/2) is checked. Once | ||
| 182 | * it is crossed, the oldest opened DSO object is closed. | ||
| 183 | * | ||
| 184 | * The dso__delete function calls close_dso function to ensure the | ||
| 185 | * data file descriptor gets closed/unmapped before the dso object | ||
| 186 | * is freed. | ||
| 187 | * | ||
| 188 | * TODO | ||
| 189 | */ | ||
| 152 | int dso__data_fd(struct dso *dso, struct machine *machine); | 190 | int dso__data_fd(struct dso *dso, struct machine *machine); |
| 153 | void dso__data_close(struct dso *dso); | 191 | void dso__data_close(struct dso *dso); |
| 154 | 192 | ||
