]> source.dussan.org Git - rspamd.git/commitdiff
* Use mlock to speed up classifiers by locking statfiles in the RAM.
authorVsevolod Stakhov <vsevolod@rambler-co.ru>
Fri, 5 Oct 2012 16:37:54 +0000 (20:37 +0400)
committerVsevolod Stakhov <vsevolod@rambler-co.ru>
Fri, 5 Oct 2012 16:37:54 +0000 (20:37 +0400)
src/main.c
src/statfile.c
src/statfile.h

index 8bdcc5979a7bde745d20cdadde634bbc38010912..406df0adfb2f983f2f7b7e609094a7aa0d52e51f 100644 (file)
@@ -401,6 +401,8 @@ fork_worker (struct rspamd_main *rspamd, struct worker_conf *cf)
                case 0:
                        /* Update pid for logging */
                        update_log_pid (cf->type, rspamd->logger);
+                       /* Lock statfile pool if possible */
+                       statfile_pool_lockall (rspamd->statfile_pool);
                        /* Drop privilleges */
                        drop_priv (rspamd);
                        /* Set limits */
index 15c41550a307970acf657cf085b3d683d30b1522..0c1cee2e04d4e3ae17ddf5b3449530cdcafca89d 100644 (file)
@@ -214,6 +214,7 @@ statfile_pool_new (memory_pool_t *pool, size_t max_size)
        new->max = max_size;
        new->files = memory_pool_alloc0 (new->pool, STATFILES_MAX * sizeof (stat_file_t));
        new->lock = memory_pool_get_mutex (new->pool);
+       new->mlock_ok = TRUE;
 
        return new;
 }
@@ -375,7 +376,14 @@ statfile_pool_open (statfile_pool_t * pool, gchar *filename, size_t size, gboole
 
        rspamd_strlcpy (new_file->filename, filename, sizeof (new_file->filename));
        new_file->len = st.st_size;
-       /* Aqquire lock for this operation */
+       /* Try to lock pages in RAM */
+       if (pool->mlock_ok) {
+               if (mlock (new_file->map, new_file->len) == -1) {
+                       msg_warn ("mlock of statfile failed, maybe you need to increase RLIMIT_MEMLOCK limit for a process: %s", strerror (errno));
+                       pool->mlock_ok = FALSE;
+               }
+       }
+       /* Acquire lock for this operation */
        lock_file (new_file->fd, FALSE);
        if (statfile_pool_check (new_file) == -1) {
                pool->opened--;
@@ -948,4 +956,22 @@ get_statfile_by_symbol (statfile_pool_t *pool, struct classifier_config *ccf,
     return res;
 }
 
+void
+statfile_pool_lockall (statfile_pool_t *pool)
+{
+       stat_file_t *file;
+       gint i;
+
+       if (pool->mlock_ok) {
+               for (i = 0; i < pool->opened; i ++) {
+                       file = &pool->files[i];
+                       if (mlock (file->map, file->len) == -1) {
+                               msg_warn ("mlock of statfile failed, maybe you need to increase RLIMIT_MEMLOCK limit for a process: %s", strerror (errno));
+                               pool->mlock_ok = FALSE;
+                               return;
+                       }
+               }
+       }
+       /* Do not try to lock if mlock failed */
+}
 
index edb58e5db72a8afea8ac5daf2e743f670be2f3a1..5f7e856e53b4917f26de17fe0f4cedd7d838a409 100644 (file)
@@ -94,6 +94,7 @@ typedef struct statfile_pool_s {
        memory_pool_mutex_t *lock;                              /**< mutex                                                              */
        struct event  *invalidate_event;        /**< event for pool invalidation        */
        struct timeval invalidate_tv;
+       gboolean mlock_ok;                                              /**< whether it is possible to use mlock (2) to avoid statfiles unloading */
 } statfile_pool_t;
 
 /* Forwarded declarations */
@@ -139,6 +140,12 @@ gint statfile_pool_close (statfile_pool_t *pool, stat_file_t *file, gboolean kee
  */
 void statfile_pool_delete (statfile_pool_t *pool);
 
+/**
+ * Try to lock all statfiles in memory
+ * @param pool statfile pool object
+ */
+void statfile_pool_lockall (statfile_pool_t *pool);
+
 /**
  * Lock specified file for exclusive use (eg. learning)
  * @param pool statfile pool object