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)
{
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
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;
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 */
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) {
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);
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
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));
}
}
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) {
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,
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));
}
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);
}
module_init (kpr_initialise);
module_exit (kpr_finalise);
+EXPORT_SYMBOL (kpr_control_interface);
EXPORT_SYMBOL (kpr_router_interface);