Commit 54489ba1 authored by Evan Hunt's avatar Evan Hunt
Browse files

Improve locking performance in dispatch.c

3316.	[tuning]	Improved locking performance when recursing.
			[RT #28836]

   - Use one lock per memory pool instead of associating
     them all with a single 'pool_lock' in the dispatch manager.
   - Reduce the critical sections for qid->lock in get_dispsocket(),
     deref_portentry() and dns_dispatch_addresponse2().
   - Added a memory pool for socket events in dns_dispatch_t.
   - Add an isc_socketevent_t member in the resquery_t object, and use
     it with isc_socket_sendto2() instead of using isc_socket_sendto()
   - Tuned the memory pools in dispatch.c for better performance
     under load
parent 5416b924
3316. [tuning] Improved locking performance when recursing.
[RT #28836]
3315. [tuning] Use multiple dispatch objects for sending upstream
queries; this can improve performance on busy
multiprocessor systems by reducing lock contention.
......
This diff is collapsed.
......@@ -25,8 +25,9 @@
#include <isc/print.h>
#include <isc/string.h>
#include <isc/random.h>
#include <isc/task.h>
#include <isc/socket.h>
#include <isc/stats.h>
#include <isc/task.h>
#include <isc/timer.h>
#include <isc/util.h>
......@@ -143,6 +144,7 @@ typedef struct query {
isc_buffer_t buffer;
isc_buffer_t *tsig;
dns_tsigkey_t *tsigkey;
isc_socketevent_t sendevent;
unsigned int options;
unsigned int attributes;
unsigned int sends;
......@@ -1194,7 +1196,8 @@ process_sendevent(resquery_t *query, isc_event_t *event) {
}
}
isc_event_free(&event);
if (event->ev_type == ISC_SOCKEVENT_CONNECT)
isc_event_free(&event);
if (retry) {
/*
......@@ -1990,8 +1993,11 @@ resquery_send(resquery_t *query) {
* XXXRTH Make sure we don't send to ourselves! We should probably
* prune out these addresses when we get them from the ADB.
*/
result = isc_socket_sendto(socket, &r, task, resquery_senddone,
query, address, NULL);
ISC_EVENT_INIT(&query->sendevent, sizeof(query->sendevent), 0, NULL,
ISC_SOCKEVENT_SENDDONE, resquery_senddone, query,
NULL, NULL, NULL);
result = isc_socket_sendto2(socket, &r, task, address, NULL,
&query->sendevent, 0);
if (result != ISC_R_SUCCESS) {
if (connecting) {
/*
......
......@@ -283,12 +283,20 @@ typedef struct isc_socketmethods {
isc_task_t *task, isc_taskaction_t action,
const void *arg, isc_sockaddr_t *address,
struct in6_pktinfo *pktinfo);
isc_result_t (*sendto2)(isc_socket_t *sock, isc_region_t *region,
isc_task_t *task, isc_sockaddr_t *address,
struct in6_pktinfo *pktinfo,
isc_socketevent_t *event,
unsigned int flags);
isc_result_t (*connect)(isc_socket_t *sock, isc_sockaddr_t *addr,
isc_task_t *task, isc_taskaction_t action,
const void *arg);
isc_result_t (*recv)(isc_socket_t *sock, isc_region_t *region,
unsigned int minimum, isc_task_t *task,
isc_taskaction_t action, const void *arg);
isc_result_t (*recv2)(isc_socket_t *sock, isc_region_t *region,
unsigned int minimum, isc_task_t *task,
isc_socketevent_t *event, unsigned int flags);
void (*cancel)(isc_socket_t *sock, isc_task_t *task,
unsigned int how);
isc_result_t (*getsockname)(isc_socket_t *sock,
......
......@@ -140,6 +140,18 @@ isc_socket_sendto(isc_socket_t *sock, isc_region_t *region, isc_task_t *task,
pktinfo));
}
isc_result_t
isc_socket_sendto2(isc_socket_t *sock, isc_region_t *region,
isc_task_t *task, isc_sockaddr_t *address,
struct in6_pktinfo *pktinfo, isc_socketevent_t *event,
unsigned int flags)
{
REQUIRE(ISCAPI_SOCKET_VALID(sock));
return (sock->methods->sendto2(sock, region, task, address,
pktinfo, event, flags));
}
isc_result_t
isc_socket_connect(isc_socket_t *sock, isc_sockaddr_t *addr, isc_task_t *task,
isc_taskaction_t action, const void *arg)
......@@ -158,6 +170,17 @@ isc_socket_recv(isc_socket_t *sock, isc_region_t *region, unsigned int minimum,
return (sock->methods->recv(sock, region, minimum, task, action, arg));
}
isc_result_t
isc_socket_recv2(isc_socket_t *sock, isc_region_t *region,
unsigned int minimum, isc_task_t *task,
isc_socketevent_t *event, unsigned int flags)
{
REQUIRE(ISCAPI_SOCKET_VALID(sock));
return (sock->methods->recv2(sock, region, minimum, task,
event, flags));
}
void
isc_socket_cancel(isc_socket_t *sock, isc_task_t *task, unsigned int how) {
REQUIRE(ISCAPI_SOCKET_VALID(sock));
......
......@@ -572,8 +572,10 @@ static struct {
isc__socket_detach,
isc__socket_bind,
isc__socket_sendto,
isc__socket_sendto2,
isc__socket_connect,
isc__socket_recv,
isc__socket_recv2,
isc__socket_cancel,
isc__socket_getsockname,
isc__socket_gettype,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment