summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2020-05-19 02:58:23 +0200
committerVolker Lendecke <vl@samba.org>2020-07-08 09:42:39 +0000
commit6c68c75b2100ba95da9575350b3a9d14211a5cc7 (patch)
treefb12b64710bb61341ccde90008e2136d7c99c7f4
parentc25fb103ea8b1a822005afbc791610329fd0295a (diff)
downloadsamba-6c68c75b2100ba95da9575350b3a9d14211a5cc7.tar.gz
s3:g_lock: avoid very expensive generate_random_buffer() in g_lock_parse()
We don't require a sequence number that is incremented, we just need a value that's not reused. We use the new generate_unique_u64(), which is much cheaper! Using smbtorture3 //foo/bar -U% local-g-lock-ping-pong -o 500000 under valgrind --tool=callgrind... This change replaces this: 13,129,925,659 PROGRAM TOTALS 4,125,752,958 ???:_nettle_sha256_compress [/usr/lib/x86_64-linux-gnu/libnettle.so.6.4] 1,257,005,866 ???:_nettle_aes_encrypt [/usr/lib/x86_64-linux-gnu/libnettle.so.6.4] 590,000,773 bin/default/../../lib/tdb/common/lock.c:tdb_lock_list 571,503,429 ???:_nettle_aes_set_key [/usr/lib/x86_64-linux-gnu/libnettle.so.6.4] 479,000,608 bin/default/../../lib/tdb/common/lock.c:tdb_unlock ... by this: 6,877,826,377 PROGRAM TOTALS 590,000,773 bin/default/../../lib/tdb/common/lock.c:tdb_lock_list 479,000,608 bin/default/../../lib/tdb/common/lock.c:tdb_unlock ... 12,500,033 bin/default/../../lib/util/genrand_util.c:generate_unique_u64 ... 8,996,970 ???:_nettle_sha256_compress [/usr/lib/x86_64-linux-gnu/libnettle.so.6.4] time smbtorture3 //foo/bar -U% local-g-lock-ping-pong -o 5000000 gives: 537426 locks/sec real 0m19,071s user 0m15,061s sys 0m3,999s vs. 900956 locks/sec real 0m11,155s user 0m8,293s sys 0m2,860s Signed-off-by: Stefan Metzmacher <metze@samba.org> Reviewed-by: Volker Lendecke <vl@samba.org>
-rw-r--r--source3/lib/g_lock.c38
1 files changed, 19 insertions, 19 deletions
diff --git a/source3/lib/g_lock.c b/source3/lib/g_lock.c
index d9843359dd1..c36539393e1 100644
--- a/source3/lib/g_lock.c
+++ b/source3/lib/g_lock.c
@@ -43,7 +43,7 @@ struct g_lock {
struct server_id exclusive;
size_t num_shared;
uint8_t *shared;
- uint64_t data_seqnum;
+ uint64_t unique_data_epoch;
size_t datalen;
uint8_t *data;
};
@@ -52,15 +52,15 @@ static bool g_lock_parse(uint8_t *buf, size_t buflen, struct g_lock *lck)
{
struct server_id exclusive;
size_t num_shared, shared_len;
- uint64_t data_seqnum;
+ uint64_t unique_data_epoch;
if (buflen < (SERVER_ID_BUF_LENGTH + /* exclusive */
sizeof(uint64_t) + /* seqnum */
sizeof(uint32_t))) { /* num_shared */
- struct g_lock ret = { .exclusive.pid = 0 };
- generate_random_buffer(
- (uint8_t *)&ret.data_seqnum,
- sizeof(ret.data_seqnum));
+ struct g_lock ret = {
+ .exclusive.pid = 0,
+ .unique_data_epoch = generate_unique_u64(0),
+ };
*lck = ret;
return true;
}
@@ -69,7 +69,7 @@ static bool g_lock_parse(uint8_t *buf, size_t buflen, struct g_lock *lck)
buf += SERVER_ID_BUF_LENGTH;
buflen -= SERVER_ID_BUF_LENGTH;
- data_seqnum = BVAL(buf, 0);
+ unique_data_epoch = BVAL(buf, 0);
buf += sizeof(uint64_t);
buflen -= sizeof(uint64_t);
@@ -90,7 +90,7 @@ static bool g_lock_parse(uint8_t *buf, size_t buflen, struct g_lock *lck)
.exclusive = exclusive,
.num_shared = num_shared,
.shared = buf,
- .data_seqnum = data_seqnum,
+ .unique_data_epoch = unique_data_epoch,
.datalen = buflen-shared_len,
.data = buf+shared_len,
};
@@ -160,7 +160,7 @@ static NTSTATUS g_lock_store(
}
server_id_put(exclusive, lck->exclusive);
- SBVAL(seqnum_buf, 0, lck->data_seqnum);
+ SBVAL(seqnum_buf, 0, lck->unique_data_epoch);
if (new_shared != NULL) {
if (lck->num_shared >= UINT32_MAX) {
@@ -967,7 +967,7 @@ static void g_lock_writev_data_fn(
return;
}
- lck.data_seqnum += 1;
+ lck.unique_data_epoch = generate_unique_u64(lck.unique_data_epoch);
lck.data = NULL;
lck.datalen = 0;
state->status = g_lock_store(
@@ -1207,7 +1207,7 @@ struct g_lock_watch_data_state {
TDB_DATA key;
struct server_id blocker;
bool blockerdead;
- uint64_t data_seqnum;
+ uint64_t unique_data_epoch;
NTSTATUS status;
};
@@ -1231,9 +1231,9 @@ static void g_lock_watch_data_send_fn(
state->status = NT_STATUS_INTERNAL_DB_CORRUPTION;
return;
}
- state->data_seqnum = lck.data_seqnum;
+ state->unique_data_epoch = lck.unique_data_epoch;
- DBG_DEBUG("state->data_seqnum=%"PRIu64"\n", state->data_seqnum);
+ DBG_DEBUG("state->unique_data_epoch=%"PRIu64"\n", state->unique_data_epoch);
subreq = dbwrap_watched_watch_send(
state, state->ev, rec, state->blocker);
@@ -1305,11 +1305,11 @@ static void g_lock_watch_data_done_fn(
return;
}
- if (lck.data_seqnum != state->data_seqnum) {
- DBG_DEBUG("lck.data_seqnum=%"PRIu64", "
- "state->data_seqnum=%"PRIu64"\n",
- lck.data_seqnum,
- state->data_seqnum);
+ if (lck.unique_data_epoch != state->unique_data_epoch) {
+ DBG_DEBUG("lck.unique_data_epoch=%"PRIu64", "
+ "state->unique_data_epoch=%"PRIu64"\n",
+ lck.unique_data_epoch,
+ state->unique_data_epoch);
state->status = NT_STATUS_OK;
return;
}
@@ -1394,7 +1394,7 @@ static void g_lock_wake_watchers_fn(
return;
}
- lck.data_seqnum += 1;
+ lck.unique_data_epoch = generate_unique_u64(lck.unique_data_epoch);
status = g_lock_store(rec, &lck, NULL, NULL, 0);
if (!NT_STATUS_IS_OK(status)) {