-/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=4:tabstop=4:
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
*
- * Copyright (C) 2001, 2002 Cluster File Systems, Inc.
+ * GPL HEADER START
*
- * This file is part of Lustre, http://www.lustre.org.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
- * Lustre is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
*
- * Lustre is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
*
- * You should have received a copy of the GNU General Public License
- * along with Lustre; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
*/
#define DEBUG_SUBSYSTEM S_LNET
cfs_mem_cache_t *cfs_page_t_slab = NULL;
cfs_mem_cache_t *cfs_page_p_slab = NULL;
+cfs_page_t * virt_to_page(void * addr)
+{
+ cfs_page_t *pg;
+ pg = cfs_mem_cache_alloc(cfs_page_t_slab, 0);
+
+ if (NULL == pg) {
+ cfs_enter_debugger();
+ return NULL;
+ }
+
+ memset(pg, 0, sizeof(cfs_page_t));
+ pg->addr = (void *)((__u64)addr & (~((__u64)PAGE_SIZE-1)));
+ pg->mapping = addr;
+ cfs_atomic_set(&pg->count, 1);
+ cfs_set_bit(PG_virt, &(pg->flags));
+ cfs_enter_debugger();
+ return pg;
+}
+
/*
* cfs_alloc_page
* To allocate the cfs_page_t and also 1 page of memory
* N/A
*/
+cfs_atomic_t libcfs_total_pages;
+
cfs_page_t * cfs_alloc_page(int flags)
{
cfs_page_t *pg;
memset(pg, 0, sizeof(cfs_page_t));
pg->addr = cfs_mem_cache_alloc(cfs_page_p_slab, 0);
- atomic_set(&pg->count, 1);
+ cfs_atomic_set(&pg->count, 1);
if (pg->addr) {
if (cfs_is_flag_set(flags, CFS_ALLOC_ZERO)) {
memset(pg->addr, 0, CFS_PAGE_SIZE);
}
+ cfs_atomic_inc(&libcfs_total_pages);
} else {
cfs_enter_debugger();
cfs_mem_cache_free(cfs_page_t_slab, pg);
{
ASSERT(pg != NULL);
ASSERT(pg->addr != NULL);
- ASSERT(atomic_read(&pg->count) <= 1);
+ ASSERT(cfs_atomic_read(&pg->count) <= 1);
- cfs_mem_cache_free(cfs_page_p_slab, pg->addr);
+ if (!cfs_test_bit(PG_virt, &pg->flags)) {
+ cfs_mem_cache_free(cfs_page_p_slab, pg->addr);
+ cfs_atomic_dec(&libcfs_total_pages);
+ } else {
+ cfs_enter_debugger();
+ }
cfs_mem_cache_free(cfs_page_t_slab, pg);
}
+int cfs_mem_is_in_cache(const void *addr, const cfs_mem_cache_t *kmem)
+{
+ KdPrint(("cfs_mem_is_in_cache: not implemented. (should maintain a"
+ "chain to keep all allocations traced.)\n"));
+ return 1;
+}
/*
* cfs_alloc
void *
cfs_alloc(size_t nr_bytes, u_int32_t flags)
{
- void *ptr;
+ void *ptr;
/* Ignore the flags: always allcoate from NonPagedPool */
-
- ptr = ExAllocatePoolWithTag(NonPagedPool, nr_bytes, 'Lufs');
-
- if (ptr != NULL && (flags & CFS_ALLOC_ZERO)) {
- memset(ptr, 0, nr_bytes);
+ ptr = ExAllocatePoolWithTag(NonPagedPool, nr_bytes, 'Lufs');
+ if (ptr != NULL && (flags & CFS_ALLOC_ZERO)) {
+ memset(ptr, 0, nr_bytes);
}
if (!ptr) {
cfs_enter_debugger();
}
- return ptr;
+ return ptr;
}
/*
void
cfs_free(void *addr)
{
- ExFreePool(addr);
+ ExFreePool(addr);
}
/*
void *
cfs_alloc_large(size_t nr_bytes)
{
- return cfs_alloc(nr_bytes, 0);
+ return cfs_alloc(nr_bytes, 0);
}
/*
void
cfs_free_large(void *addr)
{
- cfs_free(addr);
+ cfs_free(addr);
}
}
memset(kmc, 0, sizeof(cfs_mem_cache_t));
-
kmc->flags = flags;
if (name) {
{
ExFreeToNPagedLookasideList(&(kmc->npll), buf);
}
+
+cfs_spinlock_t shrinker_guard = {0};
+CFS_LIST_HEAD(shrinker_hdr);
+cfs_timer_t shrinker_timer = {0};
+
+struct cfs_shrinker * cfs_set_shrinker(int seeks, shrink_callback cb)
+{
+ struct cfs_shrinker * s = (struct cfs_shrinker *)
+ cfs_alloc(sizeof(struct cfs_shrinker), CFS_ALLOC_ZERO);
+ if (s) {
+ s->cb = cb;
+ s->seeks = seeks;
+ s->nr = 2;
+ cfs_spin_lock(&shrinker_guard);
+ cfs_list_add(&s->list, &shrinker_hdr);
+ cfs_spin_unlock(&shrinker_guard);
+ }
+
+ return s;
+}
+
+void cfs_remove_shrinker(struct cfs_shrinker *s)
+{
+ struct cfs_shrinker *tmp;
+ cfs_spin_lock(&shrinker_guard);
+#if TRUE
+ cfs_list_for_each_entry_typed(tmp, &shrinker_hdr,
+ struct cfs_shrinker, list) {
+ if (tmp == s) {
+ cfs_list_del(&tmp->list);
+ break;
+ }
+ }
+#else
+ cfs_list_del(&s->list);
+#endif
+ cfs_spin_unlock(&shrinker_guard);
+ cfs_free(s);
+}
+
+/* time ut test proc */
+void shrinker_timer_proc(ulong_ptr_t arg)
+{
+ struct cfs_shrinker *s;
+ cfs_spin_lock(&shrinker_guard);
+
+ cfs_list_for_each_entry_typed(s, &shrinker_hdr,
+ struct cfs_shrinker, list) {
+ s->cb(s->nr, __GFP_FS);
+ }
+ cfs_spin_unlock(&shrinker_guard);
+ cfs_timer_arm(&shrinker_timer, 300);
+}
+
+int start_shrinker_timer()
+{
+ /* initialize shriner timer */
+ cfs_timer_init(&shrinker_timer, shrinker_timer_proc, NULL);
+
+ /* start the timer to trigger in 5 minutes */
+ cfs_timer_arm(&shrinker_timer, 300);
+
+ return 0;
+}
+
+void stop_shrinker_timer()
+{
+ /* cancel the timer */
+ cfs_timer_disarm(&shrinker_timer);
+ cfs_timer_done(&shrinker_timer);
+}