IB/opa_vnic: Fixes for RC
cover IB/opa_vnic: Fixes for RC
Hi Doug,
Continuing with our 4.14 rc material here is a series dedicated to vnic. These are pretty minor. If you'd rather wait and push off to for-next and put into 4.15 that's OK as well. I do have a 2 patch series coming up that does add new functionality so I'll submit that against for-next specifically.
Patches can can also be found in my GitHub repo at:
https://github.com/ddalessa/kernel/tree/for-4.14
---
Niranjana Vishwanathapura (6):
IB/opa_vnic: Mark unused Ethernet MTU fields as reserved IB/opa_vnic: Set POD value for Ethernet MTU IB/opa_vnic: Allow reset of MAC address IB/opa_vnic: Properly return the total MACs in UC MAC list IB/opa_vnic: Properly set vesw port status IB/opa_vnic: Add routing control information
Scott Franco (1):
IB/opa_vnic: Properly clear Mac Table Digest
drivers/infiniband/ulp/opa_vnic/opa_vnic_encap.c | 42 ++++++++++++++++++- drivers/infiniband/ulp/opa_vnic/opa_vnic_encap.h | 22 ++++++++-- .../infiniband/ulp/opa_vnic/opa_vnic_internal.h | 7 ++- drivers/infiniband/ulp/opa_vnic/opa_vnic_netdev.c | 44 ++++++++++++++------ drivers/infiniband/ulp/opa_vnic/opa_vnic_vema.c | 1 .../infiniband/ulp/opa_vnic/opa_vnic_vema_iface.c | 22 +++++----- 6 files changed, 103 insertions(+), 35 deletions(-)
--
-Denny
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
A message that is not in the archive (sent off-list or not yet received): 20170926134250.11429.58329.stgit-9QXIwq+3FY+1XWohqUldA0EOCMrvLtNR@public.gmane.org
PATCH 1/7 IB/opa_vnic: Mark unused Ethernet MTU fields as reserved
From: Niranjana Vishwanathapura <niranjana.vishwanathapura-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
Per pcp mtu fields are not used, mark them as reserved.
--- drivers/infiniband/ulp/opa_vnic/opa_vnic_encap.h | 8 +++----- .../infiniband/ulp/opa_vnic/opa_vnic_internal.h | 5 ++--- drivers/infiniband/ulp/opa_vnic/opa_vnic_netdev.c | 2 +- .../infiniband/ulp/opa_vnic/opa_vnic_vema_iface.c | 10 ++-------- 4 files changed, 8 insertions(+), 17 deletions(-)
drivers/infiniband/ulp/opa_vnic/opa_vnic_encap.h +3 -5
@@ -111,8 +111,7 @@* @pkey: partition key * @u_mcast_dlid: unknown multicast dlid * @u_ucast_dlid: array of unknown unicast dlids -* @eth_mtu: MTUs for each vlan PCP -* @eth_mtu_non_vlan: MTU for non vlan packets +* @eth_mtu: Ethernet MTU */ struct opa_vesw_info {__be16 fabric_id;
@@ -128,9 +127,8 @@ struct opa_vesw_info {__be32 u_mcast_dlid;__be32 u_ucast_dlid[OPA_VESW_MAX_NUM_DEF_PORT ]; -u8 rsvd3[44 ]; -__be16 eth_mtu[OPA_VNIC_MAX_NUM_PCP ]; -__be16 eth_mtu_non_vlan; +u8 rsvd3[60 ]; +__be16 eth_mtu;u8 rsvd4[2 ]; } __packed;
drivers/infiniband/ulp/opa_vnic/opa_vnic_internal.h +2 -3
@@ -89,9 +89,8 @@ struct __opa_vesw_info {u32 u_mcast_dlid;u32 u_ucast_dlid[OPA_VESW_MAX_NUM_DEF_PORT ]; -u8 rsvd3[44 ]; -u16 eth_mtu[OPA_VNIC_MAX_NUM_PCP ]; -u16 eth_mtu_non_vlan; +u8 rsvd3[60 ]; +u16 eth_mtu;u8 rsvd4[2 ]; } __packed;
drivers/infiniband/ulp/opa_vnic/opa_vnic_netdev.c +1 -1
@@ -140,7 +140,7 @@ void opa_vnic_process_vema_config(struct opa_vnic_adapter *adapter)/* Handle MTU limit change */ rtnl_lock (); - netdev->max_mtu = max_t(unsigned int, info->vesw.eth_mtu_non_vlan, + netdev->max_mtu = max_t(unsigned int, info->vesw.eth_mtu, netdev->min_mtu);if (netdev->mtu > netdev->max_mtu)dev_set_mtu (netdev, netdev->max_mtu);
drivers/infiniband/ulp/opa_vnic/opa_vnic_vema_iface.c +2 -8
@@ -177,10 +177,7 @@ void opa_vnic_get_vesw_info(struct opa_vnic_adapter *adapter, info->u_ucast_dlid[i] =cpu_to_be32 (src->u_ucast_dlid[i]);memcpy (info->rsvd3, src->rsvd3,ARRAY_SIZE (src->rsvd3)); -for (i =0 ; i <OPA_VNIC_MAX_NUM_PCP ; i++) - info->eth_mtu[i] =cpu_to_be16 (src->eth_mtu[i]); - - info->eth_mtu_non_vlan =cpu_to_be16 (src->eth_mtu_non_vlan); + info->eth_mtu =cpu_to_be16 (src->eth_mtu);memcpy (info->rsvd4, src->rsvd4,ARRAY_SIZE (src->rsvd4)); }
@@ -212,10 +209,7 @@ void opa_vnic_set_vesw_info(struct opa_vnic_adapter *adapter, dst->u_ucast_dlid[i] =be32_to_cpu (info->u_ucast_dlid[i]);memcpy (dst->rsvd3, info->rsvd3,ARRAY_SIZE (info->rsvd3)); -for (i =0 ; i <OPA_VNIC_MAX_NUM_PCP ; i++) - dst->eth_mtu[i] =be16_to_cpu (info->eth_mtu[i]); - - dst->eth_mtu_non_vlan =be16_to_cpu (info->eth_mtu_non_vlan); + dst->eth_mtu =be16_to_cpu (info->eth_mtu);memcpy (dst->rsvd4, info->rsvd4,ARRAY_SIZE (info->rsvd4)); }
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 2/7 IB/opa_vnic: Set POD value for Ethernet MTU
In reply to a message not in the archiveFrom: Niranjana Vishwanathapura <niranjana.vishwanathapura-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
Set power on default value of 1500 for eth_mtu.
--- drivers/infiniband/ulp/opa_vnic/opa_vnic_netdev.c | 1 + drivers/infiniband/ulp/opa_vnic/opa_vnic_vema.c | 1 + 2 files changed, 2 insertions(+), 0 deletions(-)
drivers/infiniband/ulp/opa_vnic/opa_vnic_netdev.c +1 -0
@@ -183,6 +183,7 @@ static inline void opa_vnic_set_pod_values(struct opa_vnic_adapter *adapter) adapter->info.vport.max_smac_ent =OPA_VNIC_MAX_SMAC_LIMIT ; adapter->info.vport.config_state =OPA_VNIC_STATE_DROP_ALL ; adapter->info.vport.eth_link_status =OPA_VNIC_ETH_LINK_DOWN ; + adapter->info.vesw.eth_mtu =ETH_DATA_LEN ; }/* opa_vnic_set_mac_addr - change mac address */
drivers/infiniband/ulp/opa_vnic/opa_vnic_vema.c +1 -0
@@ -186,6 +186,7 @@ static inline void vema_get_pod_values(struct opa_veswport_info *port_info)cpu_to_be16 (OPA_VNIC_MAX_SMAC_LIMIT ); port_info->vport.oper_state =OPA_VNIC_STATE_DROP_ALL ; port_info->vport.config_state =OPA_VNIC_STATE_DROP_ALL ; + port_info->vesw.eth_mtu =cpu_to_be16 (ETH_DATA_LEN ); }/**
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 3/7 IB/opa_vnic: Allow reset of MAC address
In reply to a message not in the archiveFrom: Niranjana Vishwanathapura <niranjana.vishwanathapura-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
Ensure MAC address is reset while deleting the vesw port.
--- drivers/infiniband/ulp/opa_vnic/opa_vnic_netdev.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
drivers/infiniband/ulp/opa_vnic/opa_vnic_netdev.c +1 -1
@@ -130,7 +130,7 @@ void opa_vnic_process_vema_config(struct opa_vnic_adapter *adapter)memcpy (saddr.sa_data, info->vport.base_mac_addr,ARRAY_SIZE (info->vport.base_mac_addr));mutex_lock (&adapter->lock); -eth_mac_addr (netdev, &saddr); +eth_commit_mac_addr_change (netdev, &saddr);memcpy (adapter->vema_mac_addr, info->vport.base_mac_addr,ETH_ALEN );mutex_unlock (&adapter->lock);
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 4/7 IB/opa_vnic: Properly return the total MACs in UC MAC list
In reply to a message not in the archiveFrom: Niranjana Vishwanathapura <niranjana.vishwanathapura-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
Do not include EM specified MAC address in total MACs of the UC MAC list.
--- .../infiniband/ulp/opa_vnic/opa_vnic_vema_iface.c | 8 +++++--- 1 files changed, 5 insertions(+), 3 deletions(-)
drivers/infiniband/ulp/opa_vnic/opa_vnic_vema_iface.c +5 -3
@@ -342,7 +342,7 @@ void opa_vnic_query_mcast_macs(struct opa_vnic_adapter *adapter,void opa_vnic_query_ucast_macs (struct opa_vnic_adapter *adapter,struct opa_veswport_iface_macs *macs) { -u16 start_idx, tot_macs, num_macs, idx =0 , count =0 ; +u16 start_idx, tot_macs, num_macs, idx =0 , count =0 , em_macs =0 ;struct netdev_hw_addr *ha; start_idx =be16_to_cpu (macs->start_idx);
@@ -353,8 +353,10 @@ void opa_vnic_query_ucast_macs(struct opa_vnic_adapter *adapter,/* Do not include EM specified MAC address */ if (!memcmp (adapter->info.vport.base_mac_addr, ha->addr, -ARRAY_SIZE (adapter->info.vport.base_mac_addr))) +ARRAY_SIZE (adapter->info.vport.base_mac_addr))) { + em_macs++;continue ; + }if (start_idx > idx++)continue ;
@@ -377,7 +379,7 @@ void opa_vnic_query_ucast_macs(struct opa_vnic_adapter *adapter, } tot_macs =netdev_hw_addr_list_count (&adapter->netdev->dev_addrs) + -netdev_uc_count (adapter->netdev); +netdev_uc_count (adapter->netdev) - em_macs; macs->tot_macs_in_lst =cpu_to_be16 (tot_macs); macs->num_macs_in_msg =cpu_to_be16 (count); macs->gen_count =cpu_to_be16 (adapter->info.vport.uc_macs_gen_count);
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 5/7 IB/opa_vnic: Properly clear Mac Table Digest
In reply to a message not in the archiveFrom: Scott Franco <[email protected]>
Clear the MAC table digest when the MAC table is freed.
--- drivers/infiniband/ulp/opa_vnic/opa_vnic_encap.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-)
drivers/infiniband/ulp/opa_vnic/opa_vnic_encap.c +1 -0
@@ -139,6 +139,7 @@ void opa_vnic_release_mac_tbl(struct opa_vnic_adapter *adapter)rcu_assign_pointer (adapter->mactbl,NULL );synchronize_rcu ();opa_vnic_free_mac_tbl (mactbl); + adapter->info.vport.mac_tbl_digest =0 ;mutex_unlock (&adapter->mactbl_lock); }
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 6/7 IB/opa_vnic: Properly set vesw port status
In reply to a message not in the archiveFrom: Niranjana Vishwanathapura <niranjana.vishwanathapura-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
Update eth_link_status and operating status information to represent the overall status of the virtual Ethernet switch port.
--- drivers/infiniband/ulp/opa_vnic/opa_vnic_netdev.c | 39 +++++++++++++++------ 1 files changed, 27 insertions(+), 12 deletions(-)
drivers/infiniband/ulp/opa_vnic/opa_vnic_netdev.c +27 -12
@@ -112,6 +112,27 @@ static u16 opa_vnic_select_queue(struct net_device *netdev, struct sk_buff *skb,return rc; } +static void opa_vnic_update_state (struct opa_vnic_adapter *adapter,bool up) +{ +struct __opa_veswport_info *info = &adapter->info; + +mutex_lock (&adapter->lock); +/* Operational state can only be DROP_ALL or FORWARDING */ +if ((info->vport.config_state ==OPA_VNIC_STATE_FORWARDING ) && up) { + info->vport.oper_state =OPA_VNIC_STATE_FORWARDING ; + info->vport.eth_link_status =OPA_VNIC_ETH_LINK_UP ; + }else { + info->vport.oper_state =OPA_VNIC_STATE_DROP_ALL ; + info->vport.eth_link_status =OPA_VNIC_ETH_LINK_DOWN ; + } + +if (info->vport.config_state ==OPA_VNIC_STATE_FORWARDING ) +netif_dormant_off (adapter->netdev); +else +netif_dormant_on (adapter->netdev); +mutex_unlock (&adapter->lock); +} +/* opa_vnic_process_vema_config - process vema configuration updates */ void opa_vnic_process_vema_config (struct opa_vnic_adapter *adapter) {
@@ -164,14 +185,8 @@ void opa_vnic_process_vema_config(struct opa_vnic_adapter *adapter) adapter->flow_tbl[i] = port_count ? port_num[i % port_count] :OPA_VNIC_INVALID_PORT ; -/* Operational state can only be DROP_ALL or FORWARDING */ -if (info->vport.config_state ==OPA_VNIC_STATE_FORWARDING ) { - info->vport.oper_state =OPA_VNIC_STATE_FORWARDING ; -netif_dormant_off (netdev); - }else { - info->vport.oper_state =OPA_VNIC_STATE_DROP_ALL ; -netif_dormant_on (netdev); - } +/* update state */ +opa_vnic_update_state (adapter, !!(netdev->flags &IFF_UP )); }/*
@@ -269,8 +284,8 @@ static int opa_netdev_open(struct net_device *netdev)return rc; } -/* Update eth link status and send trap */ - adapter->info.vport.eth_link_status =OPA_VNIC_ETH_LINK_UP ; +/* Update status and send trap */ +opa_vnic_update_state (adapter, true);opa_vnic_vema_report_event (adapter,OPA_VESWPORT_TRAP_ETH_LINK_STATUS_CHANGE );return 0 ;
@@ -288,8 +303,8 @@ static int opa_netdev_close(struct net_device *netdev)return rc; } -/* Update eth link status and send trap */ - adapter->info.vport.eth_link_status =OPA_VNIC_ETH_LINK_DOWN ; +/* Update status and send trap */ +opa_vnic_update_state (adapter, false);opa_vnic_vema_report_event (adapter,OPA_VESWPORT_TRAP_ETH_LINK_STATUS_CHANGE );return 0 ;
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 7/7 IB/opa_vnic: Add routing control information
In reply to a message not in the archiveFrom: Niranjana Vishwanathapura <niranjana.vishwanathapura-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
Add protocol specific routing control information in the encapsulation header as per the configuration.
--- drivers/infiniband/ulp/opa_vnic/opa_vnic_encap.c | 41 +++++++++++++++++++- drivers/infiniband/ulp/opa_vnic/opa_vnic_encap.h | 16 +++++++- .../infiniband/ulp/opa_vnic/opa_vnic_internal.h | 4 +- .../infiniband/ulp/opa_vnic/opa_vnic_vema_iface.c | 4 ++ 4 files changed, 61 insertions(+), 4 deletions(-)
drivers/infiniband/ulp/opa_vnic/opa_vnic_encap.c +39 -2
@@ -406,6 +406,42 @@ u8 opa_vnic_get_vl(struct opa_vnic_adapter *adapter, struct sk_buff *skb)return vl; } +/* opa_vnic_get_rc - return the routing control */ +static u8 opa_vnic_get_rc (struct __opa_veswport_info *info, +struct sk_buff *skb) +{ +u8 proto, rout_ctrl; + +switch (vlan_get_protocol (skb)) { +case htons (ETH_P_IPV6 ): + proto =ipv6_hdr (skb)->nexthdr; +if (proto ==IPPROTO_TCP ) + rout_ctrl =OPA_VNIC_ENCAP_RC_EXT (info->vesw.rc, +IPV6_TCP ); +else if (proto ==IPPROTO_UDP ) + rout_ctrl =OPA_VNIC_ENCAP_RC_EXT (info->vesw.rc, +IPV6_UDP ); +else + rout_ctrl =OPA_VNIC_ENCAP_RC_EXT (info->vesw.rc,IPV6 ); +break ; +case htons (ETH_P_IP ): + proto =ip_hdr (skb)->protocol; +if (proto ==IPPROTO_TCP ) + rout_ctrl =OPA_VNIC_ENCAP_RC_EXT (info->vesw.rc, +IPV4_TCP ); +else if (proto ==IPPROTO_UDP ) + rout_ctrl =OPA_VNIC_ENCAP_RC_EXT (info->vesw.rc, +IPV4_UDP ); +else + rout_ctrl =OPA_VNIC_ENCAP_RC_EXT (info->vesw.rc,IPV4 ); +break ; +default : + rout_ctrl =OPA_VNIC_ENCAP_RC_EXT (info->vesw.rc,DEFAULT ); + } + +return rout_ctrl; +} +/* opa_vnic_calc_entropy - calculate the packet entropy */ u8 opa_vnic_calc_entropy (struct opa_vnic_adapter *adapter,struct sk_buff *skb) {
@@ -448,7 +484,7 @@ void opa_vnic_encap_skb(struct opa_vnic_adapter *adapter, struct sk_buff *skb) {struct __opa_veswport_info *info = &adapter->info;struct opa_vnic_skb_mdata *mdata; -u8 def_port, sc, entropy, *hdr; +u8 def_port, sc, rc, entropy, *hdr;u16 len, l4_hdr;u32 dlid;
@@ -459,6 +495,7 @@ void opa_vnic_encap_skb(struct opa_vnic_adapter *adapter, struct sk_buff *skb) len =opa_vnic_wire_length (skb); dlid =opa_vnic_get_dlid (adapter, skb, def_port); sc =opa_vnic_get_sc (info, skb); + rc =opa_vnic_get_rc (info, skb); l4_hdr = info->vesw.vesw_id; mdata =skb_push (skb,sizeof (*mdata));
@@ -471,6 +508,6 @@ void opa_vnic_encap_skb(struct opa_vnic_adapter *adapter, struct sk_buff *skb) }opa_vnic_make_header (hdr, info->vport.encap_slid, dlid, len, - info->vesw.pkey, entropy, sc,0 , + info->vesw.pkey, entropy, sc, rc,OPA_VNIC_L4_ETHR , l4_hdr); }
drivers/infiniband/ulp/opa_vnic/opa_vnic_encap.h +15 -1
@@ -103,6 +103,17 @@#define OPA_VNIC_ETH_LINK_UP 1#define OPA_VNIC_ETH_LINK_DOWN 2 +/* routing control */ +#define OPA_VNIC_ENCAP_RC_DEFAULT 0 +#define OPA_VNIC_ENCAP_RC_IPV4 4 +#define OPA_VNIC_ENCAP_RC_IPV4_UDP 8 +#define OPA_VNIC_ENCAP_RC_IPV4_TCP 12 +#define OPA_VNIC_ENCAP_RC_IPV6 16 +#define OPA_VNIC_ENCAP_RC_IPV6_TCP 20 +#define OPA_VNIC_ENCAP_RC_IPV6_UDP 24 + +#define OPA_VNIC_ENCAP_RC_EXT (w, b) (((w) >> OPA_VNIC_ENCAP_RC_ ## b) & 0x7) +/** * struct opa_vesw_info - OPA vnic switch information * @fabric_id: 10-bit fabric id
@@ -111,6 +122,7 @@* @pkey: partition key * @u_mcast_dlid: unknown multicast dlid * @u_ucast_dlid: array of unknown unicast dlids +* @rc: routing control * @eth_mtu: Ethernet MTU */ struct opa_vesw_info {
@@ -127,7 +139,9 @@ struct opa_vesw_info {__be32 u_mcast_dlid;__be32 u_ucast_dlid[OPA_VESW_MAX_NUM_DEF_PORT ]; -u8 rsvd3[60 ]; +__be32 rc; + +u8 rsvd3[56 ];__be16 eth_mtu;u8 rsvd4[2 ]; } __packed;
drivers/infiniband/ulp/opa_vnic/opa_vnic_internal.h +3 -1
@@ -89,7 +89,9 @@ struct __opa_vesw_info {u32 u_mcast_dlid;u32 u_ucast_dlid[OPA_VESW_MAX_NUM_DEF_PORT ]; -u8 rsvd3[60 ]; +u32 rc; + +u8 rsvd3[56 ];u16 eth_mtu;u8 rsvd4[2 ]; } __packed;
drivers/infiniband/ulp/opa_vnic/opa_vnic_vema_iface.c +4 -0
@@ -176,6 +176,8 @@ void opa_vnic_get_vesw_info(struct opa_vnic_adapter *adapter,for (i =0 ; i <OPA_VESW_MAX_NUM_DEF_PORT ; i++) info->u_ucast_dlid[i] =cpu_to_be32 (src->u_ucast_dlid[i]); + info->rc =cpu_to_be32 (src->rc); +memcpy (info->rsvd3, src->rsvd3,ARRAY_SIZE (src->rsvd3)); info->eth_mtu =cpu_to_be16 (src->eth_mtu);memcpy (info->rsvd4, src->rsvd4,ARRAY_SIZE (src->rsvd4));
@@ -208,6 +210,8 @@ void opa_vnic_set_vesw_info(struct opa_vnic_adapter *adapter,for (i =0 ; i <OPA_VESW_MAX_NUM_DEF_PORT ; i++) dst->u_ucast_dlid[i] =be32_to_cpu (info->u_ucast_dlid[i]); + dst->rc =be32_to_cpu (info->rc); +memcpy (dst->rsvd3, info->rsvd3,ARRAY_SIZE (info->rsvd3)); dst->eth_mtu =be16_to_cpu (info->eth_mtu);memcpy (dst->rsvd4, info->rsvd4,ARRAY_SIZE (info->rsvd4));
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Quoted 7 lines · Dennis Dalessandro
Hi Doug,
Continuing with our 4.14 rc material here is a series dedicated to vnic. These
are pretty minor. If you'd rather wait and push off to for-next and put into
4.15 that's OK as well.
Yes, I think that's what I'd like to do with this series. This series looks fine for next to me. I'll address the other two in their thread.
Signature · 8 lines
Doug Ledford <[email protected]> GPG KeyID: B826A3330E572FDD Key fingerprint = AE6B 1BDA 122B 23B4 265B 1274 B826 A333 0E57 2FDD -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html