components/openvswitch/files/lib/dpif-solaris.c
changeset 7112 dab9beb5bc49
parent 6924 e8aaad6b5075
child 7237 c378a893371d
equal deleted inserted replaced
7111:a0e4f5518caa 7112:dab9beb5bc49
    37 #include "vlog.h"
    37 #include "vlog.h"
    38 #include <netpacket/packet.h>
    38 #include <netpacket/packet.h>
    39 #include <zone.h>
    39 #include <zone.h>
    40 #include <libdllink.h>
    40 #include <libdllink.h>
    41 
    41 
       
    42 #ifndef	MAC_OFPORT_ARRAY
       
    43 /*
       
    44  * Keeping a bitbucket of each containing 64-bits (uint64_t)
       
    45  * for kernel ofports to effectively lookup a free ofport.
       
    46  */
       
    47 #define	MAC_OFPORT_ARRAY		(MAC_OF_MAXPORT/64)
       
    48 #define	MAC_OFPORT_ARRAY_MASK		0x3F
       
    49 #define	MAC_OFPORT_ARRAY_SHIFT		6
       
    50 #endif
       
    51 
    42 VLOG_DEFINE_THIS_MODULE(dpif_solaris);
    52 VLOG_DEFINE_THIS_MODULE(dpif_solaris);
    43 
    53 
    44 static kstat2_handle_t	dpif_khandle;
    54 static kstat2_handle_t	dpif_khandle;
    45 static boolean_t	kstat2_handle_initialized = B_FALSE;
    55 static boolean_t	kstat2_handle_initialized = B_FALSE;
    46 static struct ovs_mutex	kstat_mutex = OVS_MUTEX_INITIALIZER;
    56 static struct ovs_mutex	kstat_mutex = OVS_MUTEX_INITIALIZER;
       
    57 static struct ovs_mutex dp_ports_bitvector_mutex = OVS_MUTEX_INITIALIZER;
       
    58 uint64_t dp_ports_bitvector[MAC_OFPORT_ARRAY];
    47 
    59 
    48 /* Datapath interface for the openvswitch Solaris kernel module. */
    60 /* Datapath interface for the openvswitch Solaris kernel module. */
    49 struct dpif_solaris {
    61 struct dpif_solaris {
    50 	struct dpif dpif;
    62 	struct dpif dpif;
    51 	dladm_handle_t dh;
    63 	dladm_handle_t dh;
   517 	    port->name, port->port_no);
   529 	    port->name, port->port_no);
   518 
   530 
   519 	return (0);
   531 	return (0);
   520 }
   532 }
   521 
   533 
   522 static boolean_t
       
   523 port_no_used(struct dpif_solaris *dpif, uint32_t port_no)
       
   524     OVS_REQ_WRLOCK(dp->port_rwlock)
       
   525 {
       
   526 	struct dpif_solaris_port *port;
       
   527 
       
   528 	HMAP_FOR_EACH(port, node, &dpif->ports) {
       
   529 		if (port->port_no == port_no)
       
   530 			return (true);
       
   531 	}
       
   532 	return (false);
       
   533 }
       
   534 
       
   535 /*
   534 /*
   536  * Choose an unused, non-zero port number and return it on success.
   535  * Choose an unused, non-zero port number and return it on success.
   537  * Return ODPP_NONE on failure.
   536  * Return ODPP_NONE on failure.
   538  * The current approach to choose unused port number is quite inefficient,
   537  * The current approach to choose unused port number is quite inefficient,
   539  * need improvement. TBD
   538  * need improvement. TBD
   540  */
   539  */
   541 static odp_port_t
   540 static odp_port_t
   542 choose_port(struct dpif_solaris *dpif)
   541 choose_port(void)
   543     OVS_REQ_WRLOCK(dp->port_rwlock)
       
   544 {
   542 {
   545 	uint32_t port_no;
   543 	uint32_t port_no;
   546 
   544 	uint64_t chk_bit;
       
   545 	ovs_mutex_lock(&dp_ports_bitvector_mutex);
   547 	for (port_no = PORT_PF_PACKET_UPLINK + 1;
   546 	for (port_no = PORT_PF_PACKET_UPLINK + 1;
   548 	    port_no < MAC_OF_MAXPORT; port_no++) {
   547 	    port_no < MAC_OF_MAXPORT; port_no++) {
   549 		if (port_no_used(dpif, port_no))
   548 		chk_bit = dp_ports_bitvector[port_no >> MAC_OFPORT_ARRAY_SHIFT];
       
   549 		if ((chk_bit & (1LL << (port_no & MAC_OFPORT_ARRAY_MASK))) > 0)
   550 			continue;
   550 			continue;
   551 
   551 
       
   552 		dp_ports_bitvector[port_no >> MAC_OFPORT_ARRAY_SHIFT] |=
       
   553 		    (1LL << (port_no & MAC_OFPORT_ARRAY_MASK));
       
   554 		ovs_mutex_unlock(&dp_ports_bitvector_mutex);
       
   555 		VLOG_DBG("dpif_solaris_choose_port: port no: %d", port_no);
   552 		return (u32_to_odp(port_no));
   556 		return (u32_to_odp(port_no));
   553 	}
   557 	}
   554 
   558 	ovs_mutex_unlock(&dp_ports_bitvector_mutex);
   555 	return (ODPP_NONE);
   559 	return (ODPP_NONE);
       
   560 }
       
   561 
       
   562 static void
       
   563 reset_port(uint32_t port_no)
       
   564 {
       
   565 	ovs_mutex_lock(&dp_ports_bitvector_mutex);
       
   566 	dp_ports_bitvector[port_no >> MAC_OFPORT_ARRAY_SHIFT] &=
       
   567 	    ~(1LL << (port_no & MAC_OFPORT_ARRAY_MASK));
       
   568 	ovs_mutex_unlock(&dp_ports_bitvector_mutex);
   556 }
   569 }
   557 
   570 
   558 static boolean_t
   571 static boolean_t
   559 pf_port_no_used(struct dpif_solaris *dpif, uint32_t pf_port_no)
   572 pf_port_no_used(struct dpif_solaris *dpif, uint32_t pf_port_no)
   560 {
   573 {
   779 	}
   792 	}
   780 	ovs_rwlock_wrlock(&dpif->upcall_lock);
   793 	ovs_rwlock_wrlock(&dpif->upcall_lock);
   781 	ovs_rwlock_wrlock(&dpif->port_rwlock);
   794 	ovs_rwlock_wrlock(&dpif->port_rwlock);
   782 
   795 
   783 	if (*port_nop == ODPP_NONE) {
   796 	if (*port_nop == ODPP_NONE) {
   784 		*port_nop = choose_port(dpif);
   797 		*port_nop = choose_port();
   785 		if (*port_nop == ODPP_NONE) {
   798 		if (*port_nop == ODPP_NONE) {
   786 			error = EFBIG;
   799 			error = EFBIG;
   787 			goto fail;
   800 			goto fail;
   788 		}
   801 		}
   789 	}
   802 	}
   839 	hmap_insert(&dpif->ports, &port->node, hash_odp_port(port->port_no));
   852 	hmap_insert(&dpif->ports, &port->node, hash_odp_port(port->port_no));
   840 	ovs_rwlock_unlock(&dpif->port_rwlock);
   853 	ovs_rwlock_unlock(&dpif->port_rwlock);
   841 	ovs_rwlock_unlock(&dpif->upcall_lock);
   854 	ovs_rwlock_unlock(&dpif->upcall_lock);
   842 	return (0);
   855 	return (0);
   843 fail:
   856 fail:
       
   857 	if (*port_nop != ODPP_NONE)
       
   858 		reset_port(odp_to_u32(*port_nop));
       
   859 
   844 	if (port != NULL) {
   860 	if (port != NULL) {
   845 		if (port->xfd != -1)
   861 		if (port->xfd != -1)
   846 			(void) close(port->xfd);
   862 			(void) close(port->xfd);
   847 		dpif_solaris_destroy_port_channel(dpif, port);
   863 		dpif_solaris_destroy_port_channel(dpif, port);
   848 		free(port->name);
   864 		free(port->name);
   956 			    "%s", port->name);
   972 			    "%s", port->name);
   957 		}
   973 		}
   958 	}
   974 	}
   959 	VLOG_DBG("dpif_solaris_port_del %s close xfd %d", port->name,
   975 	VLOG_DBG("dpif_solaris_port_del %s close xfd %d", port->name,
   960 	    port->xfd);
   976 	    port->xfd);
       
   977 
       
   978 	reset_port(port->port_no);
   961 
   979 
   962 	free(port->type);
   980 	free(port->type);
   963 	free(port->name);
   981 	free(port->name);
   964 	free(port->linkname);
   982 	free(port->linkname);
   965 	free(port->physname);
   983 	free(port->physname);