Whamcloud - gitweb
smash the HEAD with the contents of b_cmd. HEAD_PRE_CMD_SMASH and
[fs/lustre-release.git] / lnet / router / router.c
index 9fb6afe..d0dbf0a 100644 (file)
@@ -48,6 +48,13 @@ kpr_router_interface_t kpr_router_interface = {
        kprri_deregister:       kpr_deregister_nal,
 };
 
+kpr_control_interface_t kpr_control_interface = {
+       kprci_add_route:        kpr_add_route,
+       kprci_del_route:        kpr_del_route,
+       kprci_get_route:        kpr_get_route,
+       kprci_notify:           kpr_sys_notify,
+};
+
 int
 kpr_register_nal (kpr_nal_interface_t *nalif, void **argp)
 {
@@ -282,9 +289,18 @@ kpr_shutdown_nal (void *arg)
        LASSERT (!ne->kpne_shutdown);
        LASSERT (!in_interrupt());
 
-       write_lock_irqsave (&kpr_rwlock, flags);
+       write_lock_irqsave (&kpr_rwlock, flags); /* locking a bit spurious... */
        ne->kpne_shutdown = 1;
-       write_unlock_irqrestore (&kpr_rwlock, flags);
+       write_unlock_irqrestore (&kpr_rwlock, flags); /* except it's a memory barrier */
+
+       while (atomic_read (&ne->kpne_refcount) != 0)
+       {
+               CDEBUG (D_NET, "Waiting for refcount on NAL %d to reach zero (%d)\n",
+                       ne->kpne_interface.kprni_nalid, atomic_read (&ne->kpne_refcount));
+
+               set_current_state (TASK_UNINTERRUPTIBLE);
+               schedule_timeout (HZ);
+       }
 }
 
 void
@@ -296,21 +312,14 @@ kpr_deregister_nal (void *arg)
         CDEBUG (D_NET, "Deregister NAL %d\n", ne->kpne_interface.kprni_nalid);
 
        LASSERT (ne->kpne_shutdown);            /* caller must have issued shutdown already */
+       LASSERT (atomic_read (&ne->kpne_refcount) == 0); /* can't be busy */
        LASSERT (!in_interrupt());
 
        write_lock_irqsave (&kpr_rwlock, flags);
-       list_del (&ne->kpne_list);
-       write_unlock_irqrestore (&kpr_rwlock, flags);
 
-        /* Wait until all outstanding messages/notifications have completed */
-       while (atomic_read (&ne->kpne_refcount) != 0)
-       {
-               CDEBUG (D_NET, "Waiting for refcount on NAL %d to reach zero (%d)\n",
-                       ne->kpne_interface.kprni_nalid, atomic_read (&ne->kpne_refcount));
+       list_del (&ne->kpne_list);
 
-               set_current_state (TASK_UNINTERRUPTIBLE);
-               schedule_timeout (HZ);
-       }
+       write_unlock_irqrestore (&kpr_rwlock, flags);
 
        PORTAL_FREE (ne, sizeof (*ne));
         PORTAL_MODULE_UNUSE;
@@ -368,14 +377,11 @@ kpr_lookup_target (void *arg, ptl_nid_t target_nid, int nob,
 
         CDEBUG (D_NET, "lookup "LPX64" from NAL %d\n", target_nid, 
                 ne->kpne_interface.kprni_nalid);
-        LASSERT (!in_interrupt());
-
-       read_lock (&kpr_rwlock);
 
-       if (ne->kpne_shutdown) {        /* caller is shutting down */
-                read_unlock (&kpr_rwlock);
+       if (ne->kpne_shutdown)          /* caller is shutting down */
                return (-ENOENT);
-        }
+
+       read_lock (&kpr_rwlock);
 
        /* Search routes for one that has a gateway to target_nid on the callers network */
 
@@ -446,26 +452,25 @@ kpr_forward_packet (void *arg, kpr_fwd_desc_t *fwd)
        struct list_head    *e;
         kpr_route_entry_t   *re;
         kpr_nal_entry_t     *tmp_ne;
-        int                  rc;
 
         CDEBUG (D_NET, "forward [%p] "LPX64" from NAL %d\n", fwd,
                 target_nid, src_ne->kpne_interface.kprni_nalid);
 
         LASSERT (nob == lib_kiov_nob (fwd->kprfd_niov, fwd->kprfd_kiov));
-        LASSERT (!in_interrupt());
-
-       read_lock (&kpr_rwlock);
+        
+        atomic_inc (&kpr_queue_depth);
+       atomic_inc (&src_ne->kpne_refcount); /* source nal is busy until fwd completes */
 
         kpr_fwd_packets++;                   /* (loose) stats accounting */
         kpr_fwd_bytes += nob + sizeof(ptl_hdr_t);
 
-       if (src_ne->kpne_shutdown) {         /* caller is shutting down */
-                rc = -ESHUTDOWN;
+       if (src_ne->kpne_shutdown)           /* caller is shutting down */
                goto out;
-        }
 
        fwd->kprfd_router_arg = src_ne;      /* stash caller's nal entry */
 
+       read_lock (&kpr_rwlock);
+
        /* Search routes for one that has a gateway to target_nid NOT on the caller's network */
 
         list_for_each (e, &kpr_routes) {
@@ -502,9 +507,7 @@ kpr_forward_packet (void *arg, kpr_fwd_desc_t *fwd)
                 kpr_update_weight (ge, nob);
 
                 fwd->kprfd_gateway_nid = ge->kpge_nid;
-                atomic_inc (&src_ne->kpne_refcount); /* source and dest nals are */
-                atomic_inc (&dst_ne->kpne_refcount); /* busy until fwd completes */
-                atomic_inc (&kpr_queue_depth);
+                atomic_inc (&dst_ne->kpne_refcount); /* dest nal is busy until fwd completes */
 
                 read_unlock (&kpr_rwlock);
 
@@ -517,16 +520,18 @@ kpr_forward_packet (void *arg, kpr_fwd_desc_t *fwd)
                 return;
        }
 
-        rc = -EHOSTUNREACH;
+        read_unlock (&kpr_rwlock);
  out:
         kpr_fwd_errors++;
 
-        CDEBUG (D_NET, "Failed to forward [%p] "LPX64" from NAL %d: %d\n", 
-                fwd, target_nid, src_ne->kpne_interface.kprni_nalid, rc);
+        CDEBUG (D_NET, "Failed to forward [%p] "LPX64" from NAL %d\n", fwd,
+                target_nid, src_ne->kpne_interface.kprni_nalid);
 
-       (fwd->kprfd_callback)(fwd->kprfd_callback_arg, rc);
+       /* Can't find anywhere to forward to */
+       (fwd->kprfd_callback)(fwd->kprfd_callback_arg, -EHOSTUNREACH);
 
-        read_unlock (&kpr_rwlock);
+        atomic_dec (&kpr_queue_depth);
+       atomic_dec (&src_ne->kpne_refcount);
 }
 
 void
@@ -630,7 +635,7 @@ kpr_add_route (int gateway_nalid, ptl_nid_t gateway_nid,
 
 int
 kpr_sys_notify (int gateway_nalid, ptl_nid_t gateway_nid,
-                int alive, time_t when)
+            int alive, time_t when)
 {
         return (kpr_do_notify (0, gateway_nalid, gateway_nid, alive, when));
 }
@@ -689,12 +694,11 @@ kpr_del_route (int gw_nalid, ptl_nid_t gw_nid,
 }
 
 int
-kpr_get_route (int idx, __u32 *gateway_nalid, ptl_nid_t *gateway_nid,
-               ptl_nid_t *lo_nid, ptl_nid_t *hi_nid, __u32 *alive)
+kpr_get_route (int idx, int *gateway_nalid, ptl_nid_t *gateway_nid,
+               ptl_nid_t *lo_nid, ptl_nid_t *hi_nid, int *alive)
 {
        struct list_head  *e;
 
-        LASSERT (!in_interrupt());
        read_lock(&kpr_rwlock);
 
         for (e = kpr_routes.next; e != &kpr_routes; e = e->next) {
@@ -718,67 +722,11 @@ kpr_get_route (int idx, __u32 *gateway_nalid, ptl_nid_t *gateway_nid,
         return (-ENOENT);
 }
 
-static int 
-kpr_nal_cmd(struct portals_cfg *pcfg, void * private)
-{
-        int err = -EINVAL;
-        ENTRY;
-
-        switch(pcfg->pcfg_command) {
-        default:
-                CDEBUG(D_IOCTL, "Inappropriate cmd: %d\n", pcfg->pcfg_command);
-                break;
-                
-        case NAL_CMD_ADD_ROUTE:
-                CDEBUG(D_IOCTL, "Adding route: [%d] "LPU64" : "LPU64" - "LPU64"\n",
-                       pcfg->pcfg_nal, pcfg->pcfg_nid, 
-                       pcfg->pcfg_nid2, pcfg->pcfg_nid3);
-                err = kpr_add_route(pcfg->pcfg_gw_nal, pcfg->pcfg_nid,
-                                    pcfg->pcfg_nid2, pcfg->pcfg_nid3);
-                break;
-
-        case NAL_CMD_DEL_ROUTE:
-                CDEBUG (D_IOCTL, "Removing routes via [%d] "LPU64" : "LPU64" - "LPU64"\n",
-                        pcfg->pcfg_gw_nal, pcfg->pcfg_nid, 
-                        pcfg->pcfg_nid2, pcfg->pcfg_nid3);
-                err = kpr_del_route (pcfg->pcfg_gw_nal, pcfg->pcfg_nid,
-                                     pcfg->pcfg_nid2, pcfg->pcfg_nid3);
-                break;
-
-        case NAL_CMD_NOTIFY_ROUTER: {
-                CDEBUG (D_IOCTL, "Notifying peer [%d] "LPU64" %s @ %ld\n",
-                        pcfg->pcfg_gw_nal, pcfg->pcfg_nid,
-                        pcfg->pcfg_flags ? "Enabling" : "Disabling",
-                        (time_t)pcfg->pcfg_nid3);
-                
-                err = kpr_sys_notify (pcfg->pcfg_gw_nal, pcfg->pcfg_nid,
-                                      pcfg->pcfg_flags, (time_t)pcfg->pcfg_nid3);
-                break;
-        }
-                
-        case NAL_CMD_GET_ROUTE:
-                CDEBUG (D_IOCTL, "Getting route [%d]\n", pcfg->pcfg_count);
-                err = kpr_get_route(pcfg->pcfg_count, &pcfg->pcfg_gw_nal,
-                                    &pcfg->pcfg_nid, 
-                                    &pcfg->pcfg_nid2, &pcfg->pcfg_nid3,
-                                    &pcfg->pcfg_flags);
-                break;
-        }
-        RETURN(err);
-}
-
-
 static void /*__exit*/
 kpr_finalise (void)
 {
         LASSERT (list_empty (&kpr_nals));
 
-        libcfs_nal_cmd_unregister(ROUTER);
-
-        PORTAL_SYMBOL_UNREGISTER(kpr_router_interface);
-
-        kpr_proc_fini();
-
         while (!list_empty (&kpr_routes)) {
                 kpr_route_entry_t *re = list_entry(kpr_routes.next,
                                                    kpr_route_entry_t,
@@ -788,6 +736,11 @@ kpr_finalise (void)
                 PORTAL_FREE(re, sizeof (*re));
         }
 
+        kpr_proc_fini();
+
+        PORTAL_SYMBOL_UNREGISTER(kpr_router_interface);
+        PORTAL_SYMBOL_UNREGISTER(kpr_control_interface);
+
         CDEBUG(D_MALLOC, "kpr_finalise: kmem back to %d\n",
                atomic_read(&portal_kmemory));
 }
@@ -795,20 +748,13 @@ kpr_finalise (void)
 static int __init
 kpr_initialise (void)
 {
-        int     rc;
-        
         CDEBUG(D_MALLOC, "kpr_initialise: kmem %d\n",
                atomic_read(&portal_kmemory));
 
         kpr_proc_init();
 
-        rc = libcfs_nal_cmd_register(ROUTER, kpr_nal_cmd, NULL);
-        if (rc != 0) {
-                CERROR("Can't register nal cmd handler\n");
-                return (rc);
-        }
-        
         PORTAL_SYMBOL_REGISTER(kpr_router_interface);
+        PORTAL_SYMBOL_REGISTER(kpr_control_interface);
         return (0);
 }
 
@@ -819,4 +765,5 @@ MODULE_LICENSE("GPL");
 module_init (kpr_initialise);
 module_exit (kpr_finalise);
 
+EXPORT_SYMBOL (kpr_control_interface);
 EXPORT_SYMBOL (kpr_router_interface);