in libptlctl.a for userspace utils too.
* addr@net - style nids working with > 1 local network
* router part of portals; ptl_send() uses it to chose the NI, but NALs
still do am-i-there-yet forwarding. NAL interface changed to match.
* reworked nal commands into PtlCtl(ni, cmd, arg) and rewired portals ioctl
handling. PtlFailNid, now just another PtlCtl. NAL interface includes
ctl handler.
* commented out all lconf portals config, except setting the NID (pending
socknal working out its own interfaces)
* removed all portals config from zeroconf and llmount
* "lctl network" on its own lists all local NIDs (replaces shownid).
Most (all?) portals config commands still work from lctl.
* simplified NAL setup/teardown (no separate nal_cmd and router init)
static inline void
ptl_ni_decref(ptl_ni_t *ni)
{
+ /* CAVEAT EMPTOR! must NOT be holding PTL_LOCK() (deadlock) */
LASSERT (atomic_read(&ni->ni_refcount) > 0);
if (atomic_dec_and_test(&ni->ni_refcount))
ptl_queue_zombie_ni(ni);
static inline void
ptl_ni_decref(ptl_ni_t *ni)
{
+ /* CAVEAT EMPTOR! must NOT be holding PTL_LOCK() (deadlock) */
LASSERT (atomic_read(&ni->ni_refcount) > 0);
if (atomic_dec_and_test(&ni->ni_refcount))
ptl_queue_zombie_ni(ni);
void klonal_shutdown (ptl_ni_t *ni);
ptl_err_t klonal_send (ptl_ni_t *ni, void *private,
ptl_msg_t *ptlmsg, ptl_hdr_t *hdr,
- int type, ptl_nid_t nid, ptl_pid_t pid,
+ int type, ptl_process_id_t tgt, int routing,
unsigned int payload_niov,
struct iovec *payload_iov,
size_t payload_offset, size_t payload_nob);
ptl_err_t klonal_send_pages (ptl_ni_t *ni, void *private,
ptl_msg_t *ptlmsg, ptl_hdr_t *hdr,
- int type, ptl_nid_t nid, ptl_pid_t pid,
+ int type, ptl_process_id_t tgt, int routing,
unsigned int payload_niov,
ptl_kiov_t *payload_kiov,
size_t payload_offset, size_t payload_nob);
#include "lonal.h"
ptl_err_t
-klonal_send (ptl_ni_t *ni,
- void *private,
- ptl_msg_t *ptlmsg,
- ptl_hdr_t *hdr,
- int type,
- ptl_nid_t nid,
- ptl_pid_t pid,
- unsigned int payload_niov,
- struct iovec *payload_iov,
- size_t payload_offset,
- size_t payload_nob)
+klonal_send (ptl_ni_t *ni,
+ void *private,
+ ptl_msg_t *ptlmsg,
+ ptl_hdr_t *hdr,
+ int type,
+ ptl_process_id_t target,
+ int routing,
+ unsigned int payload_niov,
+ struct iovec *payload_iov,
+ size_t payload_offset,
+ size_t payload_nob)
{
klo_desc_t klod = {
.klod_type = KLOD_IOV,
.klod_iov = { .iov = payload_iov } };
ptl_err_t rc;
+ LASSERT (!routing);
+ LASSERT (target.nid == ni->ni_nid);
+
rc = ptl_parse(ni, hdr, &klod);
if (rc == PTL_OK)
ptl_finalize(ni, private, ptlmsg, PTL_OK);
}
ptl_err_t
-klonal_send_pages (ptl_ni_t *ni,
- void *private,
- ptl_msg_t *ptlmsg,
- ptl_hdr_t *hdr,
- int type,
- ptl_nid_t nid,
- ptl_pid_t pid,
- unsigned int payload_niov,
- ptl_kiov_t *payload_kiov,
- size_t payload_offset,
- size_t payload_nob)
+klonal_send_pages (ptl_ni_t *ni,
+ void *private,
+ ptl_msg_t *ptlmsg,
+ ptl_hdr_t *hdr,
+ int type,
+ ptl_process_id_t target,
+ int routing,
+ unsigned int payload_niov,
+ ptl_kiov_t *payload_kiov,
+ size_t payload_offset,
+ size_t payload_nob)
{
klo_desc_t klod = {
.klod_type = KLOD_KIOV,
.klod_iov = { .kiov = payload_kiov } };
ptl_err_t rc;
+ LASSERT (!routing);
+ LASSERT (target.nid == ni->ni_nid);
+
rc = ptl_parse(ni, hdr, &klod);
if (rc == PTL_OK)
ptl_finalize(ni, private, ptlmsg, PTL_OK);
/* known hostname? */
if (('a' <= str[0] && str[0] <= 'z') ||
('A' <= str[0] && str[0] <= 'Z')) {
- struct hostent *he = gethostbyname(str);
-
- if (he != NULL) {
- __u32 ip = *(__u32 *)he->h_addr;
+ char *tmp;
- *addr = ntohl(ip);
- return 1;
+ PORTAL_ALLOC(tmp, nob + 1);
+ if (tmp != NULL) {
+ struct hostent *he;
+
+ memcpy(tmp, str, nob);
+ tmp[nob] = 0;
+
+ he = gethostbyname(tmp);
+
+ PORTAL_FREE(tmp, nob);
+
+ if (he != NULL) {
+ __u32 ip = *(__u32 *)he->h_addr;
+
+ *addr = ntohl(ip);
+ return 1;
+ }
}
}
#endif
list_del (&ni->ni_list);
ni->ni_shutdown = 1;
- ptl_ni_decref(ni); /* drop apini's ref (shutdown on last ref) */
ptl_apini.apini_nzombie_nis++;
- }
- PTL_UNLOCK(flags);
+ PTL_UNLOCK(flags);
- PTL_LOCK(flags);
+ ptl_ni_decref(ni); /* drop apini's ref (shutdown on last ref) */
+
+ PTL_LOCK(flags);
+ }
/* Now wait for the NI's I just nuked to show up on apini_zombie_nis
* and shut them down in guaranteed thread context */
ni = list_entry(ptl_apini.apini_zombie_nis.next,
ptl_ni_t, ni_list);
+ list_del(&ni->ni_list);
PTL_UNLOCK(flags);
PTL_LOCK(flags);
ptl_apini.apini_nzombie_nis--;
}
+ PTL_UNLOCK(flags);
}
ptl_err_t
break;
}
+ atomic_set(&ni->ni_refcount, 1);
+ atomic_inc(&nal->nal_refcount);
ni->ni_nal = nal;
ni->ni_nid = PTL_MKNID(PTL_MKNET(nal->nal_type, 0), 0);
/* for now */
- atomic_inc(&nal->nal_refcount);
-
rc = (nal->nal_startup)(ni, &interface);
if (rc != PTL_OK) {
CERROR("Error %d staring up NI %s\n",
struct list_head cull;
LASSERT (ptl_init);
- LASSERT (ptl_apini.apini_refcount > 0);
if (threshold != 0) {
/* Adding a new entry */
# This code is issued under the GNU General Public License.
# See the file COPYING in this distribution
+#
+# router is built into portals
+#
+
MOSTLYCLEANFILES = *.o *.ko *.mod.c
-DIST_SOURCES = $(kptlrouter-objs:%.o=%.c) router.h
+DIST_SOURCES = router.c proc.c router.h
ptl_nid_t gwnid;
struct list_head *e;
kpr_route_entry_t *re;
+ unsigned long flags;
ptl_ni_t *gwni = NULL;
ptl_ni_t *tmpni = NULL;
kpr_gateway_entry_t *ge = NULL;
CDEBUG (D_NET, "lookup "LPX64" from %s\n", target_nid,
(ni == NULL) ? "<>" : libcfs_nid2str(ni->ni_nid));
- LASSERT (!in_interrupt());
if (ni == NULL) { /* ni not determined yet */
gwni = ptl_net2ni(target_net); /* is it a local network? */
if (gwni != NULL) {
*nip = gwni;
- return ni->ni_nid;
+ return gwni->ni_nid;
}
+ } else if (target_net == PTL_NIDNET(ni->ni_nid)) {
+ ptl_ni_addref(ni); /* extra ref so caller can drop blindly */
+ return ni->ni_nid;
}
- read_lock (&kpr_rwlock);
+ read_lock_irqsave(&kpr_rwlock, flags);
if (ni != NULL && ni->ni_shutdown) {
/* pre-determined ni is shutting down */
- read_unlock (&kpr_rwlock);
+ read_unlock_irqrestore(&kpr_rwlock, flags);
return PTL_NID_ANY;
}
}
if (ge == NULL) {
- read_unlock (&kpr_rwlock);
+ read_unlock_irqrestore(&kpr_rwlock, flags);
LASSERT (gwni == NULL);
return PTL_NID_ANY;
kpr_update_weight (ge, nob);
gwnid = ge->kpge_nid;
- read_unlock (&kpr_rwlock);
+ read_unlock_irqrestore(&kpr_rwlock, flags);
/* NB can't deref 're/ge' after lock released! */
CDEBUG (D_NET, "lookup %s from %s: %s\n",
kpr_gateway_entry_t *ge = NULL;
ptl_ni_t *dst_ni = NULL;
ptl_ni_t *tmp_ni;
+ unsigned long flags;
struct list_head *e;
kpr_route_entry_t *re;
int rc;
libcfs_nid2str(target_nid), libcfs_nid2str(src_ni->ni_nid));
LASSERT (nob == ptl_kiov_nob (fwd->kprfd_niov, fwd->kprfd_kiov));
- LASSERT (!in_interrupt());
fwd->kprfd_src_ni = src_ni; /* stash calling ni */
- read_lock (&kpr_rwlock);
+ read_lock_irqsave(&kpr_rwlock, flags);
kpr_fwd_packets++; /* (loose) stats accounting */
kpr_fwd_bytes += nob + sizeof(ptl_hdr_t);
fwd->kprfd_gateway_nid = ge->kpge_nid;
atomic_inc (&kpr_queue_depth);
- read_unlock (&kpr_rwlock);
+ read_unlock_irqrestore(&kpr_rwlock, flags);
CDEBUG (D_NET, "forward [%p] %s: src ni %s dst ni %s gw %s\n",
fwd, libcfs_nid2str(target_nid),
(fwd->kprfd_callback)(src_ni, fwd->kprfd_callback_arg, rc);
- read_unlock (&kpr_rwlock);
+ read_unlock_irqrestore(&kpr_rwlock, flags);
}
void
re->kpre_net = net;
LASSERT(!in_interrupt());
- write_lock_irqsave (&kpr_rwlock, flags);
+ write_lock_irqsave(&kpr_rwlock, flags);
list_for_each (e, &kpr_gateways) {
kpr_gateway_entry_t *ge2 = list_entry(e, kpr_gateway_entry_t,
list_add (&re->kpre_list, &kpr_routes);
kpr_routes_generation++;
- write_unlock_irqrestore (&kpr_rwlock, flags);
+ write_unlock_irqrestore(&kpr_rwlock, flags);
return (0);
}
kpr_get_route (int idx, __u32 *net, ptl_nid_t *gateway_nid, __u32 *alive)
{
struct list_head *e;
+ unsigned long flags;
LASSERT (!in_interrupt());
- read_lock(&kpr_rwlock);
+ read_lock_irqsave(&kpr_rwlock, flags);
for (e = kpr_routes.next; e != &kpr_routes; e = e->next) {
kpr_route_entry_t *re = list_entry(e, kpr_route_entry_t,
*gateway_nid = ge->kpge_nid;
*alive = ge->kpge_alive;
- read_unlock(&kpr_rwlock);
+ read_unlock_irqrestore(&kpr_rwlock, flags);
return (0);
}
}
- read_unlock (&kpr_rwlock);
+ read_unlock_irqrestore(&kpr_rwlock, flags);
return (-ENOENT);
}