Prototype/structure update for Linux
[zfs.git] / module / zfs / arc.c
index d38d9a3..808c8e8 100644 (file)
@@ -174,9 +174,9 @@ static boolean_t arc_warm;
 /*
  * These tunables are for performance analysis.
  */
-uint64_t zfs_arc_max;
-uint64_t zfs_arc_min;
-uint64_t zfs_arc_meta_limit = 0;
+unsigned long zfs_arc_max = 0;
+unsigned long zfs_arc_min = 0;
+unsigned long zfs_arc_meta_limit = 0;
 int zfs_arc_grow_retry = 0;
 int zfs_arc_shrink_shift = 0;
 int zfs_arc_p_min_shift = 0;
@@ -523,12 +523,13 @@ static boolean_t l2arc_write_eligible(uint64_t spa_guid, arc_buf_hdr_t *ab);
  * Hash table routines
  */
 
-#define        HT_LOCK_PAD     64
+#define        HT_LOCK_ALIGN   64
+#define        HT_LOCK_PAD     (P2NPHASE(sizeof (kmutex_t), (HT_LOCK_ALIGN)))
 
 struct ht_lock {
        kmutex_t        ht_lock;
 #ifdef _KERNEL
-       unsigned char   pad[(HT_LOCK_PAD - sizeof (kmutex_t))];
+       unsigned char   pad[HT_LOCK_PAD];
 #endif
 };
 
@@ -772,8 +773,15 @@ buf_fini(void)
 {
        int i;
 
+#if defined(_KERNEL) && defined(HAVE_SPL)
+       /* Large allocations which do not require contiguous pages
+        * should be using vmem_free() in the linux kernel */
+       vmem_free(buf_hash_table.ht_table,
+           (buf_hash_table.ht_mask + 1) * sizeof (void *));
+#else
        kmem_free(buf_hash_table.ht_table,
            (buf_hash_table.ht_mask + 1) * sizeof (void *));
+#endif
        for (i = 0; i < BUF_LOCKS; i++)
                mutex_destroy(&buf_hash_table.ht_locks[i].ht_lock);
        kmem_cache_destroy(hdr_cache);
@@ -794,6 +802,8 @@ hdr_cons(void *vbuf, void *unused, int kmflag)
        refcount_create(&buf->b_refcnt);
        cv_init(&buf->b_cv, NULL, CV_DEFAULT, NULL);
        mutex_init(&buf->b_freeze_lock, NULL, MUTEX_DEFAULT, NULL);
+       list_link_init(&buf->b_arc_node);
+       list_link_init(&buf->b_l2node);
        arc_space_consume(sizeof (arc_buf_hdr_t), ARC_SPACE_HDRS);
 
        return (0);
@@ -873,8 +883,15 @@ buf_init(void)
                hsize <<= 1;
 retry:
        buf_hash_table.ht_mask = hsize - 1;
+#if defined(_KERNEL) && defined(HAVE_SPL)
+       /* Large allocations which do not require contiguous pages
+        * should be using vmem_alloc() in the linux kernel */
+       buf_hash_table.ht_table =
+           vmem_zalloc(hsize * sizeof (void*), KM_SLEEP);
+#else
        buf_hash_table.ht_table =
            kmem_zalloc(hsize * sizeof (void*), KM_NOSLEEP);
+#endif
        if (buf_hash_table.ht_table == NULL) {
                ASSERT(hsize > (1ULL << 8));
                hsize >>= 1;
@@ -1708,7 +1725,7 @@ arc_evict(arc_state_t *state, uint64_t spa, int64_t bytes, boolean_t recycle,
        mutex_exit(&state->arcs_mtx);
 
        if (bytes_evicted < bytes)
-               dprintf("only evicted %lld bytes from %x",
+               dprintf("only evicted %lld bytes from %x\n",
                    (longlong_t)bytes_evicted, state);
 
        if (skipped)
@@ -1824,7 +1841,7 @@ top:
        }
 
        if (bytes_deleted < bytes)
-               dprintf("only deleted %lld bytes from %p",
+               dprintf("only deleted %lld bytes from %p\n",
                    (longlong_t)bytes_deleted, state);
 }
 
@@ -1989,9 +2006,8 @@ arc_shrink(void)
 static int
 arc_reclaim_needed(void)
 {
-       uint64_t extra;
-
 #ifdef _KERNEL
+       uint64_t extra;
 
        if (needfree)
                return (1);
@@ -2133,7 +2149,7 @@ arc_reclaim_thread(void)
 
                /* block until needed, or one second, whichever is shorter */
                CALLB_CPR_SAFE_BEGIN(&cpr);
-               (void) cv_timedwait(&arc_reclaim_thr_cv,
+               (void) cv_timedwait_interruptible(&arc_reclaim_thr_cv,
                    &arc_reclaim_thr_lock, (ddi_get_lbolt() + hz));
                CALLB_CPR_SAFE_END(&cpr, &arc_reclaim_thr_lock);
        }
@@ -2679,7 +2695,7 @@ arc_read_nolock(zio_t *pio, spa_t *spa, const blkptr_t *bp,
     uint32_t *arc_flags, const zbookmark_t *zb)
 {
        arc_buf_hdr_t *hdr;
-       arc_buf_t *buf;
+       arc_buf_t *buf = NULL;
        kmutex_t *hash_lock;
        zio_t *rzio;
        uint64_t guid = spa_guid(spa);
@@ -2761,7 +2777,7 @@ top:
                uint64_t size = BP_GET_LSIZE(bp);
                arc_callback_t  *acb;
                vdev_t *vd = NULL;
-               uint64_t addr;
+               uint64_t addr = -1;
                boolean_t devw = B_FALSE;
 
                if (hdr == NULL) {
@@ -3039,7 +3055,7 @@ arc_release(arc_buf_t *buf, void *tag)
        arc_buf_hdr_t *hdr;
        kmutex_t *hash_lock = NULL;
        l2arc_buf_hdr_t *l2hdr;
-       uint64_t buf_size;
+       uint64_t buf_size = 0;
 
        /*
         * It would be nice to assert that if it's DMU metadata (level >
@@ -3414,7 +3430,7 @@ arc_tempreserve_space(uint64_t reserve, uint64_t txg)
         * in order to compress/encrypt/etc the data.  We therefor need to
         * make sure that there is sufficient available memory for this.
         */
-       if (error = arc_memory_throttle(reserve, anon_size, txg))
+       if ((error = arc_memory_throttle(reserve, anon_size, txg)))
                return (error);
 
        /*
@@ -4063,7 +4079,7 @@ l2arc_read_done(zio_t *zio)
 static list_t *
 l2arc_list_locked(int list_num, kmutex_t **lock)
 {
-       list_t *list;
+       list_t *list = NULL;
 
        ASSERT(list_num >= 0 && list_num <= 3);
 
@@ -4236,7 +4252,7 @@ l2arc_write_buffers(spa_t *spa, l2arc_dev_t *dev, uint64_t target_sz)
        list_t *list;
        uint64_t passed_sz, write_sz, buf_sz, headroom;
        void *buf_data;
-       kmutex_t *hash_lock, *list_lock;
+       kmutex_t *hash_lock, *list_lock = NULL;
        boolean_t have_lock, full;
        l2arc_write_callback_t *cb;
        zio_t *pio, *wzio;
@@ -4419,8 +4435,8 @@ l2arc_feed_thread(void)
 
        while (l2arc_thread_exit == 0) {
                CALLB_CPR_SAFE_BEGIN(&cpr);
-               (void) cv_timedwait(&l2arc_feed_thr_cv, &l2arc_feed_thr_lock,
-                   next);
+               (void) cv_timedwait_interruptible(&l2arc_feed_thr_cv,
+                   &l2arc_feed_thr_lock, next);
                CALLB_CPR_SAFE_END(&cpr, &l2arc_feed_thr_lock);
                next = ddi_get_lbolt() + hz;
 
@@ -4538,6 +4554,7 @@ l2arc_add_vdev(spa_t *spa, vdev_t *vd)
        adddev->l2ad_evict = adddev->l2ad_start;
        adddev->l2ad_first = B_TRUE;
        adddev->l2ad_writing = B_FALSE;
+       list_link_init(&adddev->l2ad_node);
        ASSERT3U(adddev->l2ad_write, >, 0);
 
        /*
@@ -4663,3 +4680,18 @@ l2arc_stop(void)
                cv_wait(&l2arc_feed_thr_cv, &l2arc_feed_thr_lock);
        mutex_exit(&l2arc_feed_thr_lock);
 }
+
+#if defined(_KERNEL) && defined(HAVE_SPL)
+EXPORT_SYMBOL(arc_read);
+EXPORT_SYMBOL(arc_buf_remove_ref);
+EXPORT_SYMBOL(arc_getbuf_func);
+
+module_param(zfs_arc_min, ulong, 0644);
+MODULE_PARM_DESC(zfs_arc_min, "Minimum arc size");
+
+module_param(zfs_arc_max, ulong, 0644);
+MODULE_PARM_DESC(zfs_arc_max, "Maximum arc size");
+
+module_param(zfs_arc_meta_limit, ulong, 0644);
+MODULE_PARM_DESC(zfs_arc_meta_limit, "Meta limit for arc size");
+#endif