#include "ptlrpc_internal.h"
-struct ll_rpc_opcode {
+struct ll_rpc_opcode {
__u32 opcode;
const char *opname;
} ll_rpc_opcode_table[LUSTRE_MAX_OPCODES] = {
{ OST_SAN_READ, "ost_san_read" },
{ OST_SAN_WRITE, "ost_san_write" },
{ OST_SYNCFS, "ost_syncfs" },
+ { OST_SET_INFO, "ost_set_info" },
{ MDS_GETATTR, "mds_getattr" },
{ MDS_GETATTR_NAME, "mds_getattr_name" },
{ MDS_CLOSE, "mds_close" },
{ MDS_GETSTATUS, "mds_getstatus" },
{ MDS_STATFS, "mds_statfs" },
{ MDS_GETLOVINFO, "mds_getlovinfo" },
+ { MDS_PIN, "mds_pin" },
+ { MDS_UNPIN, "mds_unpin" },
{ LDLM_ENQUEUE, "ldlm_enqueue" },
{ LDLM_CONVERT, "ldlm_convert" },
{ LDLM_CANCEL, "ldlm_cancel" },
{ PTLBD_READ, "ptlbd_read" },
{ PTLBD_WRITE, "ptlbd_write" },
{ PTLBD_FLUSH, "ptlbd_flush" },
- { OBD_PING, "obd_ping" }
+ { PTLBD_CONNECT, "ptlbd_connect" },
+ { PTLBD_DISCONNECT, "ptlbd_disconnect" },
+ { OBD_PING, "obd_ping" },
+ { OBD_LOG_CANCEL, "obd_log_cancel" },
};
const char* ll_opcode2str(__u32 opcode)
/* When one of the assertions below fail, chances are that:
* 1) A new opcode was added in lustre_idl.h, but was
* is missing from the table above.
- * or 2) The opcode space was renumbered or rearranged,
- * and the opcode_offset() function in
+ * or 2) The opcode space was renumbered or rearranged,
+ * and the opcode_offset() function in
* ptlrpc_internals.h needs to be modified.
*/
__u32 offset = opcode_offset(opcode);
void ptlrpc_lprocfs_register_service(struct obd_device *obddev,
struct ptlrpc_service *svc)
{
- struct proc_dir_entry *svc_procroot;
- struct lprocfs_counters *svc_cntrs;
+ struct proc_dir_entry *svc_procroot;
+ struct lprocfs_stats *svc_stats;
int i, rc;
- unsigned int svc_counter_config = LPROCFS_CNTR_AVGMINMAX | LPROCFS_CNTR_STDDEV;
+ unsigned int svc_counter_config = LPROCFS_CNTR_AVGMINMAX |
+ LPROCFS_CNTR_STDDEV;
LASSERT(svc->srv_procroot == NULL);
- LASSERT(svc->srv_counters == NULL);
+ LASSERT(svc->srv_stats == NULL);
svc_procroot = lprocfs_register(svc->srv_name, obddev->obd_proc_entry,
NULL, NULL);
- if (svc_procroot == NULL)
+ if (svc_procroot == NULL)
return;
-
- svc_cntrs =
- lprocfs_alloc_counters(PTLRPC_LAST_CNTR+LUSTRE_MAX_OPCODES);
- if (svc_cntrs == NULL) {
+
+ svc_stats = lprocfs_alloc_stats(PTLRPC_LAST_CNTR + LUSTRE_MAX_OPCODES);
+ if (svc_stats == NULL) {
lprocfs_remove(svc_procroot);
return;
}
-
- LPROCFS_COUNTER_INIT(svc_cntrs, PTLRPC_REQWAIT_CNTR,
- svc_counter_config,
- "req_waittime", "cycles");
- LPROCFS_COUNTER_INIT(svc_cntrs, PTLRPC_SVCEQDEPTH_CNTR,
- svc_counter_config,
- "svc_eqdepth", "reqs");
- for (i=0; i < LUSTRE_MAX_OPCODES; i++) {
+
+ lprocfs_counter_init(svc_stats, PTLRPC_REQWAIT_CNTR,
+ svc_counter_config, "req_waittime", "usec");
+ lprocfs_counter_init(svc_stats, PTLRPC_REQQDEPTH_CNTR,
+ svc_counter_config, "req_qdepth", "reqs");
+ for (i = 0; i < LUSTRE_MAX_OPCODES; i++) {
__u32 opcode = ll_rpc_opcode_table[i].opcode;
- LPROCFS_COUNTER_INIT(svc_cntrs,
- PTLRPC_LAST_CNTR+i,
- svc_counter_config,
- ll_opcode2str(opcode), "cycles");
+ lprocfs_counter_init(svc_stats, PTLRPC_LAST_CNTR + i,
+ svc_counter_config, ll_opcode2str(opcode),
+ "usec");
}
- rc = lprocfs_register_counters(svc_procroot, "service_stats",
- svc_cntrs);
+
+ rc = lprocfs_register_stats(svc_procroot, "stats", svc_stats);
if (rc < 0) {
lprocfs_remove(svc_procroot);
- lprocfs_free_counters(svc_cntrs);
+ lprocfs_free_stats(svc_stats);
} else {
svc->srv_procroot = svc_procroot;
- svc->srv_counters = svc_cntrs;
+ svc->srv_stats = svc_stats;
}
}
lprocfs_remove(svc->srv_procroot);
svc->srv_procroot = NULL;
}
- if (svc->srv_counters) {
- lprocfs_free_counters(svc->srv_counters);
- svc->srv_counters = NULL;
+ if (svc->srv_stats) {
+ lprocfs_free_stats(svc->srv_stats);
+ svc->srv_stats = NULL;
}
}
void ptlrpc_lprocfs_do_request_stat (struct ptlrpc_request *req,
- cycles_t work_start,
- cycles_t work_end)
+ long q_usec, long work_usec)
{
- int opc_offset = opcode_offset(req->rq_reqmsg->opc);
+ int opc_offset;
struct ptlrpc_service *svc = req->rq_srv_ni->sni_service;
LASSERT (svc != NULL);
- LASSERT (svc->srv_counters != NULL);
+ LASSERT (svc->srv_stats != NULL);
/* req_waittime */
- LPROCFS_COUNTER_INCR(svc->srv_counters, PTLRPC_REQWAIT_CNTR,
- (work_start - req->rq_arrival_time));
+ lprocfs_counter_add(svc->srv_stats, PTLRPC_REQWAIT_CNTR,
+ q_usec);
/* svc_eqdepth */
- LPROCFS_COUNTER_INCR(svc->srv_counters, PTLRPC_SVCEQDEPTH_CNTR,
- svc->srv_n_queued_reqs);
-
- if (opc_offset >= 0) {
- LASSERT(opc_offset < LUSTRE_MAX_OPCODES);
- LPROCFS_COUNTER_INCR(svc->srv_counters,
- PTLRPC_LAST_CNTR+opc_offset,
- work_end - work_start);
- }
+ lprocfs_counter_add(svc->srv_stats, PTLRPC_REQQDEPTH_CNTR,
+ svc->srv_n_queued_reqs);
+
+ /* stats on opc only if it's meaningful... */
+ if (req->rq_nob_received <= sizeof (struct lustre_msg) ||
+ req->rq_reqmsg->type != PTL_RPC_MSG_REQUEST)
+ return;
+
+ opc_offset = opcode_offset(req->rq_reqmsg->opc);
+ if (opc_offset < 0)
+ return;
+
+ LASSERT(opc_offset < LUSTRE_MAX_OPCODES);
+ lprocfs_counter_add(svc->srv_stats,
+ PTLRPC_LAST_CNTR+opc_offset,
+ work_usec);
}
#endif /* LPROCFS */
my ($line, $memory);
my $debug_line = 0;
+my $total = 0;
+my $max = 0;
+
while ($line = <>) {
$debug_line++;
my ($file, $func, $lno, $name, $size, $addr, $type);
- if ($line =~ m/^.*\((.*):(\d+):(.*)\(\) (\d+ \| )?\d+\+\d+\): [vk](.*) '(.*)': (\d+) at (.*) \(tot .*$/) {
+ if ($line =~ m/^.*\((.*):(\d+):(.*)\(\) (\d+ \| )?\d+\+\d+\): (k|v|slab-)(.*) '(.*)': (\d+) at (.*) \(tot (.*)\).*$/) {
$file = $1;
$lno = $2;
$func = $3;
- $type = $5;
- $name = $6;
- $size = $7;
- $addr = $8;
+ $type = $6;
+ $name = $7;
+ $size = $8;
+ $addr = $9;
+ $tot = $10;
# we can't dump the log after portals has exited, so skip "leaks"
# from memory freed in the portals module unloading.
next;
}
- if ($type eq 'malloced') {
+ if (index($type, 'alloced') >= 0) {
+ if (defined($memory->{$addr})) {
+ print STDERR "*** Two allocs with the same address ($size bytes at $addr, $file:$func:$lno)\n";
+ print STDERR " first malloc at $memory->{$addr}->{file}:$memory->{$addr}->{func}:$memory->{$addr}->{lno}, second at $file:$func:$lno\n";
+ next;
+ }
+
$memory->{$addr}->{name} = $name;
$memory->{$addr}->{size} = $size;
$memory->{$addr}->{file} = $file;
$memory->{$addr}->{func} = $func;
$memory->{$addr}->{lno} = $lno;
$memory->{$addr}->{debug_line} = $debug_line;
+
+ $total += $size;
+ if ($total > $max) {
+ $max = $total;
+ }
} else {
if (!defined($memory->{$addr})) {
print STDERR "*** Free without malloc ($size bytes at $addr, $file:$func:$lno)\n";
}
delete $memory->{$addr};
+ $total -= $size;
+ }
+ if ($total != int($tot)) {
+ print "kernel total $tot != my total $total\n";
+ $total = $tot;
}
}
print STDERR "*** Leak: $memory->{$key}->{size} bytes allocated at $key ($memory->{$key}->{file}:$memory->{$key}->{func}:$memory->{$key}->{lno}, debug file line $memory->{$key}->{debug_line})\n";
}
-print "Done.\n";
+print "maximum used: $max, amount leaked: $total\n";
#include <string.h>
#include <errno.h>
#include <sys/types.h>
+#include <sys/stat.h>
#include <stdlib.h>
#include <unistd.h>
-#define T1 "write before unlink\n"
-#define T2 "write after unlink\n"
+#define T1 "write data before unlink\n"
+#define T2 "write data after unlink\n"
char buf[128];
int main(int argc, char **argv)
{
- char *fname, *fname2;
+ char *fname, *fname2;
+ struct stat st;
int fd, rc;
if (argc < 2 || argc > 3) {
exit(1);
}
- fname = argv[1];
- if (argc == 3)
- fname2 = argv[2];
- else
- fname2 = argv[1];
+ fname = argv[1];
+ if (argc == 3)
+ fname2 = argv[2];
+ else
+ fname2 = argv[1];
fprintf(stderr, "opening\n");
fd = open(fname, O_RDWR | O_TRUNC | O_CREAT, 0644);
fprintf(stderr, "writing\n");
rc = write(fd, T1, strlen(T1) + 1);
if (rc != strlen(T1) + 1) {
- fprintf(stderr, "write (normal) %s\n", strerror(errno));
+ fprintf(stderr, "write (normal) %s (rc %d)\n",
+ strerror(errno), rc);
+ exit(1);
+ }
+
+ if (argc == 3) {
+ fprintf(stderr, "closing %s\n", fname);
+ rc = close(fd);
+ if (rc) {
+ fprintf(stderr, "close (normal) %s\n", strerror(errno));
+ exit(1);
+ }
+
+ fprintf(stderr, "opening %s\n", fname2);
+ fd = open(fname2, O_RDWR);
+ if (fd == -1) {
+ fprintf(stderr, "open (unlink) %s\n", strerror(errno));
+ exit(1);
+ }
+
+ fprintf (stderr, "unlinking %s\n", fname2);
+ rc = unlink(fname2);
+ if (rc) {
+ fprintf(stderr, "unlink %s\n", strerror(errno));
+ exit(1);
+ }
+
+ if (access(fname2, F_OK) == 0) {
+ fprintf(stderr, "%s still exists\n", fname2);
+ exit(1);
+ }
+ } else {
+ fprintf(stderr, "resetting fd offset\n");
+ rc = lseek(fd, 0, SEEK_SET);
+ if (rc) {
+ fprintf(stderr, "seek %s\n", strerror(errno));
+ exit(1);
+ }
+
+ printf("unlink %s and press enter\n", fname);
+ getc(stdin);
+ }
+
+ if (access(fname, F_OK) == 0) {
+ fprintf(stderr, "%s still exists\n", fname);
exit(1);
}
- if (argc == 3) {
- fprintf(stderr, "closing %s\n", fname);
- rc = close(fd);
- if (rc) {
- fprintf(stderr, "close (normal) %s\n", strerror(errno));
- exit(1);
- }
-
- fprintf(stderr, "opening %s\n", fname2);
- fd = open(fname2, O_RDWR);
- if (fd == -1) {
- fprintf(stderr, "open (unlink) %s\n", strerror(errno));
- exit(1);
- }
-
- fprintf (stderr, "unlinking %s\n", fname2);
- rc = unlink(fname2);
- if (rc) {
- fprintf(stderr, "unlink %s\n", strerror(errno));
- exit(1);
- }
-
- if (access(fname2, F_OK) == 0) {
- fprintf(stderr, "%s still exists\n", fname2);
- exit(1);
- }
- } else {
- printf("unlink %s and press enter\n", fname);
- getc(stdin);
- }
-
- if (access(fname, F_OK) == 0) {
- fprintf(stderr, "%s still exists\n", fname);
- exit(1);
- }
+ fprintf(stderr, "fstating\n");
+ rc = fstat(fd, &st);
+ if (rc) {
+ fprintf(stderr, "fstat (unlink) %s\n", strerror(errno));
+ exit(1);
+ }
+ if (st.st_nlink != 0)
+ fprintf(stderr, "st_nlink = %d\n", (int)st.st_nlink);
fprintf(stderr, "reading\n");
rc = read(fd, buf, strlen(T1) + 1);
if (rc != strlen(T1) + 1) {
- fprintf(stderr, "read (unlink) %s rc %d\n",
+ fprintf(stderr, "read (unlink) %s (rc %d)\n",
strerror(errno), rc);
exit(1);
}
fprintf(stderr, "truncating\n");
rc = ftruncate(fd, 0);
- if (rc ) {
+ if (rc) {
fprintf(stderr, "truncate (unlink) %s\n", strerror(errno));
exit(1);
}
fprintf(stderr, "reading again\n");
rc = read(fd, buf, strlen(T2) + 1);
if (rc != strlen(T2) + 1) {
- fprintf(stderr, "read (after unlink rewrite) %s\n",
- strerror(errno));
+ fprintf(stderr, "read (after unlink rewrite) %s (rc %d)\n",
+ strerror(errno), rc);
exit(1);
}
exit(1);
}
- fprintf(stderr, "closing again\n");
+ fprintf(stderr, "closing\n");
rc = close(fd);
if (rc) {
fprintf(stderr, "close (unlink) %s\n", strerror(errno));