1d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao/*
2d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * GPL HEADER START
3d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao *
4d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao *
6d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * This program is free software; you can redistribute it and/or modify
7d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * it under the terms of the GNU General Public License version 2 only,
8d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * as published by the Free Software Foundation.
9d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao *
10d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * This program is distributed in the hope that it will be useful, but
11d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * WITHOUT ANY WARRANTY; without even the implied warranty of
12d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * General Public License version 2 for more details (a copy is included
14d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * in the LICENSE file that accompanied this code).
15d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao *
16d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * You should have received a copy of the GNU General Public License
17d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * version 2 along with this program; If not, see
18d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
19d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao *
20d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * CA 95054 USA or visit www.sun.com if you need additional information or
22d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * have any questions.
23d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao *
24d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * GPL HEADER END
25d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao */
26d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao/*
27d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
28d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * Use is subject to license terms.
29d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao *
30d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * Copyright (c) 2012, Intel Corporation.
31d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao */
32d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao/*
33d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * This file is part of Lustre, http://www.lustre.org/
34d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * Lustre is a trademark of Sun Microsystems, Inc.
35d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao */
36d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
37d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao#define DEBUG_SUBSYSTEM S_LNET
38d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
399fdaf8c0b92ab374f8501eb47855776afc928e45Greg Kroah-Hartman#include "../../include/linux/libcfs/libcfs.h"
409fdaf8c0b92ab374f8501eb47855776afc928e45Greg Kroah-Hartman#include "../../include/linux/libcfs/libcfs_crypto.h"
419fdaf8c0b92ab374f8501eb47855776afc928e45Greg Kroah-Hartman#include "../../include/linux/lnet/lib-lnet.h"
429fdaf8c0b92ab374f8501eb47855776afc928e45Greg Kroah-Hartman#include "../../include/linux/lnet/lnet.h"
43d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao#include "tracefile.h"
44d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
45d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taovoid
46d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taokportal_memhog_free (struct libcfs_device_userstate *ldu)
47d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
48d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct page **level0p = &ldu->ldu_memhog_root_page;
49d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct page **level1p;
50d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct page **level2p;
51d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int	   count1;
52d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int	   count2;
53d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
54d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (*level0p != NULL) {
55d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
56d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		level1p = (struct page **)page_address(*level0p);
57d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		count1 = 0;
58d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
59d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		while (count1 < PAGE_CACHE_SIZE/sizeof(struct page *) &&
60d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		       *level1p != NULL) {
61d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
62d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			level2p = (struct page **)page_address(*level1p);
63d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			count2 = 0;
64d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
65d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			while (count2 < PAGE_CACHE_SIZE/sizeof(struct page *) &&
66d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			       *level2p != NULL) {
67d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
68d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				__free_page(*level2p);
69d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				ldu->ldu_memhog_pages--;
70d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				level2p++;
71d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				count2++;
72d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			}
73d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
74d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			__free_page(*level1p);
75d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			ldu->ldu_memhog_pages--;
76d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			level1p++;
77d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			count1++;
78d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		}
79d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
80d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		__free_page(*level0p);
81d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		ldu->ldu_memhog_pages--;
82d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
83d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		*level0p = NULL;
84d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
85d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
86d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	LASSERT (ldu->ldu_memhog_pages == 0);
87d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
88d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
89d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoint
90cad7aa13a34dc83daa95ae5f9deca794021b4a2aVitaly Osipovkportal_memhog_alloc(struct libcfs_device_userstate *ldu, int npages,
91cad7aa13a34dc83daa95ae5f9deca794021b4a2aVitaly Osipov		     gfp_t flags)
92d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
93d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct page **level0p;
94d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct page **level1p;
95d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct page **level2p;
96d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int	   count1;
97d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int	   count2;
98d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
99d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	LASSERT (ldu->ldu_memhog_pages == 0);
100d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	LASSERT (ldu->ldu_memhog_root_page == NULL);
101d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
102d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (npages < 0)
103d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		return -EINVAL;
104d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
105d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (npages == 0)
106d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		return 0;
107d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
108d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	level0p = &ldu->ldu_memhog_root_page;
109d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	*level0p = alloc_page(flags);
110d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (*level0p == NULL)
111d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		return -ENOMEM;
112d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	ldu->ldu_memhog_pages++;
113d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
114d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	level1p = (struct page **)page_address(*level0p);
115d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	count1 = 0;
116d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	memset(level1p, 0, PAGE_CACHE_SIZE);
117d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
118d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	while (ldu->ldu_memhog_pages < npages &&
119d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	       count1 < PAGE_CACHE_SIZE/sizeof(struct page *)) {
120d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
121d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		if (cfs_signal_pending())
122fbe7c6c72a8f36e78cf3886573bbc0fdd0aa55b5Julia Lawall			return -EINTR;
123d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
124d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		*level1p = alloc_page(flags);
125d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		if (*level1p == NULL)
126d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			return -ENOMEM;
127d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		ldu->ldu_memhog_pages++;
128d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
129d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		level2p = (struct page **)page_address(*level1p);
130d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		count2 = 0;
131d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		memset(level2p, 0, PAGE_CACHE_SIZE);
132d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
133d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		while (ldu->ldu_memhog_pages < npages &&
134d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		       count2 < PAGE_CACHE_SIZE/sizeof(struct page *)) {
135d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
136d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			if (cfs_signal_pending())
137fbe7c6c72a8f36e78cf3886573bbc0fdd0aa55b5Julia Lawall				return -EINTR;
138d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
139d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			*level2p = alloc_page(flags);
140d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			if (*level2p == NULL)
141fbe7c6c72a8f36e78cf3886573bbc0fdd0aa55b5Julia Lawall				return -ENOMEM;
142d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			ldu->ldu_memhog_pages++;
143d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
144d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			level2p++;
145d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			count2++;
146d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		}
147d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
148d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		level1p++;
149d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		count1++;
150d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
151d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
152d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	return 0;
153d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
154d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
155d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao/* called when opening /dev/device */
156d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taostatic int libcfs_psdev_open(unsigned long flags, void *args)
157d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
158d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct libcfs_device_userstate *ldu;
159d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
160d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	try_module_get(THIS_MODULE);
161d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
162d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	LIBCFS_ALLOC(ldu, sizeof(*ldu));
163d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (ldu != NULL) {
164d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		ldu->ldu_memhog_pages = 0;
165d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		ldu->ldu_memhog_root_page = NULL;
166d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
167d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	*(struct libcfs_device_userstate **)args = ldu;
168d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
1690a3bdb00710bf253ba8ba8f645645f22297c7a04Greg Kroah-Hartman	return 0;
170d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
171d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
172d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao/* called when closing /dev/device */
173d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taostatic int libcfs_psdev_release(unsigned long flags, void *args)
174d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
175d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct libcfs_device_userstate *ldu;
176d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
177d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	ldu = (struct libcfs_device_userstate *)args;
178d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (ldu != NULL) {
179d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		kportal_memhog_free(ldu);
180d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		LIBCFS_FREE(ldu, sizeof(*ldu));
181d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
182d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
183d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	module_put(THIS_MODULE);
1840a3bdb00710bf253ba8ba8f645645f22297c7a04Greg Kroah-Hartman	return 0;
185d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
186d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
187d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taostatic struct rw_semaphore ioctl_list_sem;
188d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taostatic struct list_head ioctl_list;
189d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
190d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoint libcfs_register_ioctl(struct libcfs_ioctl_handler *hand)
191d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
192d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int rc = 0;
193d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
194d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	down_write(&ioctl_list_sem);
195d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (!list_empty(&hand->item))
196d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		rc = -EBUSY;
197d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	else
198d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		list_add_tail(&hand->item, &ioctl_list);
199d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	up_write(&ioctl_list_sem);
200d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
201d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	return rc;
202d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
203d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng TaoEXPORT_SYMBOL(libcfs_register_ioctl);
204d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
205d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoint libcfs_deregister_ioctl(struct libcfs_ioctl_handler *hand)
206d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
207d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int rc = 0;
208d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
209d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	down_write(&ioctl_list_sem);
210d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (list_empty(&hand->item))
211d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		rc = -ENOENT;
212d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	else
213d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		list_del_init(&hand->item);
214d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	up_write(&ioctl_list_sem);
215d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
216d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	return rc;
217d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
218d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng TaoEXPORT_SYMBOL(libcfs_deregister_ioctl);
219d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
2201d8cb70c7bdda47125ed551fc390aa9597c5f264Greg Donaldstatic int libcfs_ioctl_int(struct cfs_psdev_file *pfile, unsigned long cmd,
221d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			    void *arg, struct libcfs_ioctl_data *data)
222d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
223d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int err = -EINVAL;
224d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
225d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	switch (cmd) {
226d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	case IOC_LIBCFS_CLEAR_DEBUG:
227d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		libcfs_debug_clear_buffer();
2280a3bdb00710bf253ba8ba8f645645f22297c7a04Greg Kroah-Hartman		return 0;
229d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	/*
230d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 * case IOC_LIBCFS_PANIC:
231d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 * Handled in arch/cfs_module.c
232d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 */
233d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	case IOC_LIBCFS_MARK_DEBUG:
234d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		if (data->ioc_inlbuf1 == NULL ||
235d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		    data->ioc_inlbuf1[data->ioc_inllen1 - 1] != '\0')
2360a3bdb00710bf253ba8ba8f645645f22297c7a04Greg Kroah-Hartman			return -EINVAL;
237d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		libcfs_debug_mark_buffer(data->ioc_inlbuf1);
2380a3bdb00710bf253ba8ba8f645645f22297c7a04Greg Kroah-Hartman		return 0;
239d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	case IOC_LIBCFS_MEMHOG:
240d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		if (pfile->private_data == NULL) {
241d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			err = -EINVAL;
242d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		} else {
243d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			kportal_memhog_free(pfile->private_data);
244d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			/* XXX The ioc_flags is not GFP flags now, need to be fixed */
245d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			err = kportal_memhog_alloc(pfile->private_data,
246d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao						   data->ioc_count,
247d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao						   data->ioc_flags);
248d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			if (err != 0)
249d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				kportal_memhog_free(pfile->private_data);
250d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		}
251d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		break;
252d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
253d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	case IOC_LIBCFS_PING_TEST: {
254d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		extern void (kping_client)(struct libcfs_ioctl_data *);
255d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		void (*ping)(struct libcfs_ioctl_data *);
256d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
257d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		CDEBUG(D_IOCTL, "doing %d pings to nid %s (%s)\n",
258d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		       data->ioc_count, libcfs_nid2str(data->ioc_nid),
259d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		       libcfs_nid2str(data->ioc_nid));
260d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		ping = symbol_get(kping_client);
261d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		if (!ping)
262d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			CERROR("symbol_get failed\n");
263d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		else {
264d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			ping(data);
265d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			symbol_put(kping_client);
266d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		}
2670a3bdb00710bf253ba8ba8f645645f22297c7a04Greg Kroah-Hartman		return 0;
268d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
269d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
270d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	default: {
271d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		struct libcfs_ioctl_handler *hand;
272d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		err = -EINVAL;
273d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		down_read(&ioctl_list_sem);
274d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		list_for_each_entry(hand, &ioctl_list, item) {
275d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			err = hand->handle_ioctl(cmd, data);
276d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			if (err != -EINVAL) {
277d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				if (err == 0)
278d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao					err = libcfs_ioctl_popdata(arg,
279d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao							data, sizeof (*data));
280d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				break;
281d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			}
282d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		}
283d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		up_read(&ioctl_list_sem);
284d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		break;
285d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
286d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
287d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
2880a3bdb00710bf253ba8ba8f645645f22297c7a04Greg Kroah-Hartman	return err;
289d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
290d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
291d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taostatic int libcfs_ioctl(struct cfs_psdev_file *pfile, unsigned long cmd, void *arg)
292d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
293d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	char    *buf;
294d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct libcfs_ioctl_data *data;
295d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int err = 0;
296d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
297d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	LIBCFS_ALLOC_GFP(buf, 1024, GFP_IOFS);
298d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (buf == NULL)
2990a3bdb00710bf253ba8ba8f645645f22297c7a04Greg Kroah-Hartman		return -ENOMEM;
300d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
301d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	/* 'cmd' and permissions get checked in our arch-specific caller */
302d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (libcfs_ioctl_getdata(buf, buf + 800, (void *)arg)) {
303d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		CERROR("PORTALS ioctl: data error\n");
304fc5c7f3dd68b4ce1d7bfac82b30c7d7a13e609b1Julia Lawall		err = -EINVAL;
305fc5c7f3dd68b4ce1d7bfac82b30c7d7a13e609b1Julia Lawall		goto out;
306d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
307d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	data = (struct libcfs_ioctl_data *)buf;
308d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
309d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	err = libcfs_ioctl_int(pfile, cmd, arg, data);
310d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
311d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoout:
312d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	LIBCFS_FREE(buf, 1024);
3130a3bdb00710bf253ba8ba8f645645f22297c7a04Greg Kroah-Hartman	return err;
314d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
315d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
316d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
317d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taostruct cfs_psdev_ops libcfs_psdev_ops = {
318d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	libcfs_psdev_open,
319d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	libcfs_psdev_release,
320d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	NULL,
321d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	NULL,
322d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	libcfs_ioctl
323d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao};
324d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
325d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoextern int insert_proc(void);
326d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoextern void remove_proc(void);
327d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng TaoMODULE_AUTHOR("Peter J. Braam <braam@clusterfs.com>");
328d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng TaoMODULE_DESCRIPTION("Portals v3.1");
329d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng TaoMODULE_LICENSE("GPL");
330d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
331c0426cf7df119c68a9715713f9dbf07862172f04Greg Kroah-Hartmanextern struct miscdevice libcfs_dev;
332d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoextern struct rw_semaphore cfs_tracefile_sem;
333d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoextern struct mutex cfs_trace_thread_mutex;
334d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoextern struct cfs_wi_sched *cfs_sched_rehash;
335d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
336d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoextern void libcfs_init_nidstrings(void);
337d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoextern int libcfs_arch_init(void);
338d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoextern void libcfs_arch_cleanup(void);
339d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
340d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taostatic int init_libcfs_module(void)
341d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
342d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int rc;
343d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
344d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	libcfs_arch_init();
345d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	libcfs_init_nidstrings();
346d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	init_rwsem(&cfs_tracefile_sem);
347d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	mutex_init(&cfs_trace_thread_mutex);
348d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	init_rwsem(&ioctl_list_sem);
349d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	INIT_LIST_HEAD(&ioctl_list);
350d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	init_waitqueue_head(&cfs_race_waitq);
351d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
352d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	rc = libcfs_debug_init(5 * 1024 * 1024);
353d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (rc < 0) {
354d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		printk(KERN_ERR "LustreError: libcfs_debug_init: %d\n", rc);
355fbe7c6c72a8f36e78cf3886573bbc0fdd0aa55b5Julia Lawall		return rc;
356d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
357d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
358d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	rc = cfs_cpu_init();
359d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (rc != 0)
360d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		goto cleanup_debug;
361d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
362d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	rc = misc_register(&libcfs_dev);
363d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (rc) {
364d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		CERROR("misc_register: error %d\n", rc);
365da7a96ae19d30dfe2564ea67afae464fafe29933Peng Tao		goto cleanup_cpu;
366d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
367d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
368d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	rc = cfs_wi_startup();
369d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (rc) {
370d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		CERROR("initialize workitem: error %d\n", rc);
371d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		goto cleanup_deregister;
372d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
373d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
374d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	/* max to 4 threads, should be enough for rehash */
375d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	rc = min(cfs_cpt_weight(cfs_cpt_table, CFS_CPT_ANY), 4);
376d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	rc = cfs_wi_sched_create("cfs_rh", cfs_cpt_table, CFS_CPT_ANY,
377d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				 rc, &cfs_sched_rehash);
378d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (rc != 0) {
379d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		CERROR("Startup workitem scheduler: error: %d\n", rc);
380d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		goto cleanup_deregister;
381d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
382d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
383d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	rc = cfs_crypto_register();
384d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (rc) {
38517afd17bdd1d52f39364fc79ca35c037504a10ccMasanari Iida		CERROR("cfs_crypto_register: error %d\n", rc);
386d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		goto cleanup_wi;
387d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
388d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
389d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
390d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	rc = insert_proc();
391d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (rc) {
392d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		CERROR("insert_proc: error %d\n", rc);
393d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		goto cleanup_crypto;
394d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
395d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
396d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	CDEBUG (D_OTHER, "portals setup OK\n");
397d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	return 0;
398d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao cleanup_crypto:
399d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	cfs_crypto_unregister();
400d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao cleanup_wi:
401d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	cfs_wi_shutdown();
402d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao cleanup_deregister:
403d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	misc_deregister(&libcfs_dev);
404da7a96ae19d30dfe2564ea67afae464fafe29933Peng Taocleanup_cpu:
405da7a96ae19d30dfe2564ea67afae464fafe29933Peng Tao	cfs_cpu_fini();
406d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao cleanup_debug:
407d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	libcfs_debug_cleanup();
408d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	return rc;
409d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
410d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
411d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taostatic void exit_libcfs_module(void)
412d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
413d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int rc;
414d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
415d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	remove_proc();
416d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
417d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	CDEBUG(D_MALLOC, "before Portals cleanup: kmem %d\n",
418d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	       atomic_read(&libcfs_kmemory));
419d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
420d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (cfs_sched_rehash != NULL) {
421d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		cfs_wi_sched_destroy(cfs_sched_rehash);
422d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		cfs_sched_rehash = NULL;
423d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
424d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
425d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	cfs_crypto_unregister();
426d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	cfs_wi_shutdown();
427d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
428d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	rc = misc_deregister(&libcfs_dev);
429d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (rc)
430d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		CERROR("misc_deregister error %d\n", rc);
431d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
432d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	cfs_cpu_fini();
433d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
434d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (atomic_read(&libcfs_kmemory) != 0)
435d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		CERROR("Portals memory leaked: %d bytes\n",
436d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		       atomic_read(&libcfs_kmemory));
437d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
438d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	rc = libcfs_debug_cleanup();
439d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (rc)
440d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		printk(KERN_ERR "LustreError: libcfs_debug_cleanup: %d\n",
441d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		       rc);
442d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
443d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	libcfs_arch_cleanup();
444d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
445d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
4466960736c01732ad952aa6c513976fa0b95166873Greg Kroah-HartmanMODULE_VERSION("1.0.0");
4476960736c01732ad952aa6c513976fa0b95166873Greg Kroah-Hartmanmodule_init(init_libcfs_module);
4486960736c01732ad952aa6c513976fa0b95166873Greg Kroah-Hartmanmodule_exit(exit_libcfs_module);
449