Whamcloud - gitweb
LU-1308 Properly add multihomed nids to peer table
[fs/lustre-release.git] / lustre / obdclass / linux / linux-module.c
index 4b6ca83..fc77287 100644 (file)
@@ -28,6 +28,8 @@
 /*
  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
+ *
+ * Copyright (c) 2011, Whamcloud, Inc.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
@@ -120,9 +122,11 @@ int obd_ioctl_getdata(char **buf, int *len, void *arg)
                 RETURN(-EINVAL);
         }
 
-        /* XXX allocate this more intelligently, using kmalloc when
-         * appropriate */
-        OBD_VMALLOC(*buf, hdr.ioc_len);
+        /* When there are lots of processes calling vmalloc on multi-core
+         * system, the high lock contention will hurt performance badly,
+         * obdfilter-survey is an example, which relies on ioctl. So we'd
+         * better avoid vmalloc on ioctl path. LU-66 */
+        OBD_ALLOC_LARGE(*buf, hdr.ioc_len);
         if (*buf == NULL) {
                 CERROR("Cannot allocate control buffer of len %d\n",
                        hdr.ioc_len);
@@ -133,13 +137,13 @@ int obd_ioctl_getdata(char **buf, int *len, void *arg)
 
         err = cfs_copy_from_user(*buf, (void *)arg, hdr.ioc_len);
         if ( err ) {
-                OBD_VFREE(*buf, hdr.ioc_len);
+                OBD_FREE_LARGE(*buf, hdr.ioc_len);
                 RETURN(err);
         }
 
         if (obd_ioctl_is_invalid(data)) {
                 CERROR("ioctl not correctly formatted\n");
-                OBD_VFREE(*buf, hdr.ioc_len);
+                OBD_FREE_LARGE(*buf, hdr.ioc_len);
                 RETURN(-EINVAL);
         }
 
@@ -198,8 +202,13 @@ static int obd_class_release(struct inode * inode, struct file * file)
 }
 
 /* to control /dev/obd */
+#ifdef HAVE_UNLOCKED_IOCTL
+static long obd_class_ioctl(struct file *filp, unsigned int cmd,
+                            unsigned long arg)
+#else
 static int obd_class_ioctl(struct inode *inode, struct file *filp,
                            unsigned int cmd, unsigned long arg)
+#endif
 {
         int err = 0;
         ENTRY;
@@ -218,7 +227,11 @@ static int obd_class_ioctl(struct inode *inode, struct file *filp,
 /* declare character device */
 static struct file_operations obd_psdev_fops = {
         .owner   = THIS_MODULE,
+#if HAVE_UNLOCKED_IOCTL
+        .unlocked_ioctl = obd_class_ioctl, /* unlocked_ioctl */
+#else
         .ioctl   = obd_class_ioctl,     /* ioctl */
+#endif
         .open    = obd_class_open,      /* open */
         .release = obd_class_release,   /* release */
 };
@@ -237,15 +250,9 @@ int obd_proc_read_version(char *page, char **start, off_t off, int count,
                           int *eof, void *data)
 {
         *eof = 1;
-#ifdef HAVE_VFS_INTENT_PATCHES
-        return snprintf(page, count, "lustre: %s\nkernel: %u\nbuild:  %s\n",
-                        LUSTRE_VERSION_STRING, LUSTRE_KERNEL_VERSION,
-                        BUILD_VERSION);
-#else
         return snprintf(page, count, "lustre: %s\nkernel: %s\nbuild:  %s\n",
                         LUSTRE_VERSION_STRING, "patchless_client",
                         BUILD_VERSION);
-#endif
 }
 
 int obd_proc_read_pinger(char *page, char **start, off_t off, int count,
@@ -285,7 +292,7 @@ static int obd_proc_read_health(char *page, char **start, off_t off,
         if (libcfs_catastrophe)
                 rc += snprintf(page + rc, count - rc, "LBUG\n");
 
-        cfs_spin_lock(&obd_dev_lock);
+        cfs_read_lock(&obd_dev_lock);
         for (i = 0; i < class_devno_max(); i++) {
                 struct obd_device *obd;
 
@@ -298,7 +305,7 @@ static int obd_proc_read_health(char *page, char **start, off_t off,
                         continue;
 
                 class_incref(obd, __FUNCTION__, cfs_current());
-                cfs_spin_unlock(&obd_dev_lock);
+                cfs_read_unlock(&obd_dev_lock);
 
                 if (obd_health_check(obd)) {
                         rc += snprintf(page + rc, count - rc,
@@ -306,9 +313,9 @@ static int obd_proc_read_health(char *page, char **start, off_t off,
                                        obd->obd_name);
                 }
                 class_decref(obd, __FUNCTION__, cfs_current());
-                cfs_spin_lock(&obd_dev_lock);
+                cfs_read_lock(&obd_dev_lock);
         }
-        cfs_spin_unlock(&obd_dev_lock);
+        cfs_read_unlock(&obd_dev_lock);
 
         if (rc == 0)
                 return snprintf(page, count, "healthy\n");