Skip to content

Commit 5f78e29

Browse files
ReiReiReidavem330
authored andcommitted
qeth: optimize IP handling in rx_mode callback
In layer3 mode of the qeth driver, multicast IP addresses from struct net_device and other type of IP addresses from other sources require mapping to the OSA-card. This patch simplifies the IP address mapping logic, and changes imple- mentation of ndo_set_rx_mode callback and ip notifier events. Addresses are stored in private hashtables instead of lists now. It allows hardware registration/removal for new/deleted multicast addresses only. Signed-off-by: Lakhvich Dmitriy <[email protected]> Signed-off-by: Ursula Braun <[email protected]> Reviewed-by: Evgeny Cherkashin <[email protected]> Reviewed-by: Thomas Richter <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 6059c90 commit 5f78e29

File tree

7 files changed

+482
-458
lines changed

7 files changed

+482
-458
lines changed

drivers/s390/net/qeth_core.h

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -561,7 +561,6 @@ enum qeth_ip_types {
561561
QETH_IP_TYPE_NORMAL,
562562
QETH_IP_TYPE_VIPA,
563563
QETH_IP_TYPE_RXIP,
564-
QETH_IP_TYPE_DEL_ALL_MC,
565564
};
566565

567566
enum qeth_cmd_buffer_state {
@@ -742,17 +741,10 @@ struct qeth_vlan_vid {
742741
unsigned short vid;
743742
};
744743

745-
enum qeth_mac_disposition {
746-
QETH_DISP_MAC_DELETE = 0,
747-
QETH_DISP_MAC_DO_NOTHING = 1,
748-
QETH_DISP_MAC_ADD = 2,
749-
};
750-
751-
struct qeth_mac {
752-
u8 mac_addr[OSA_ADDR_LEN];
753-
u8 is_uc:1;
754-
u8 disp_flag:2;
755-
struct hlist_node hnode;
744+
enum qeth_addr_disposition {
745+
QETH_DISP_ADDR_DELETE = 0,
746+
QETH_DISP_ADDR_DO_NOTHING = 1,
747+
QETH_DISP_ADDR_ADD = 2,
756748
};
757749

758750
struct qeth_rx {
@@ -800,15 +792,15 @@ struct qeth_card {
800792
unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];
801793
struct list_head vid_list;
802794
DECLARE_HASHTABLE(mac_htable, 4);
795+
DECLARE_HASHTABLE(ip_htable, 4);
796+
DECLARE_HASHTABLE(ip_mc_htable, 4);
803797
struct work_struct kernel_thread_starter;
804798
spinlock_t thread_mask_lock;
805799
unsigned long thread_start_mask;
806800
unsigned long thread_allowed_mask;
807801
unsigned long thread_running_mask;
808802
struct task_struct *recovery_task;
809803
spinlock_t ip_lock;
810-
struct list_head ip_list;
811-
struct list_head *ip_tbd_list;
812804
struct qeth_ipato ipato;
813805
struct list_head cmd_waiter_list;
814806
/* QDIO buffer handling */

drivers/s390/net/qeth_core_main.c

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1464,8 +1464,6 @@ static int qeth_setup_card(struct qeth_card *card)
14641464
card->thread_allowed_mask = 0;
14651465
card->thread_running_mask = 0;
14661466
INIT_WORK(&card->kernel_thread_starter, qeth_start_kernel_thread);
1467-
INIT_LIST_HEAD(&card->ip_list);
1468-
INIT_LIST_HEAD(card->ip_tbd_list);
14691467
INIT_LIST_HEAD(&card->cmd_waiter_list);
14701468
init_waitqueue_head(&card->wait_q);
14711469
/* initial options */
@@ -1500,11 +1498,6 @@ static struct qeth_card *qeth_alloc_card(void)
15001498
if (!card)
15011499
goto out;
15021500
QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *));
1503-
card->ip_tbd_list = kzalloc(sizeof(struct list_head), GFP_KERNEL);
1504-
if (!card->ip_tbd_list) {
1505-
QETH_DBF_TEXT(SETUP, 0, "iptbdnom");
1506-
goto out_card;
1507-
}
15081501
if (qeth_setup_channel(&card->read))
15091502
goto out_ip;
15101503
if (qeth_setup_channel(&card->write))
@@ -1517,8 +1510,6 @@ static struct qeth_card *qeth_alloc_card(void)
15171510
out_channel:
15181511
qeth_clean_channel(&card->read);
15191512
out_ip:
1520-
kfree(card->ip_tbd_list);
1521-
out_card:
15221513
kfree(card);
15231514
out:
15241515
return NULL;
@@ -4980,7 +4971,6 @@ static void qeth_core_free_card(struct qeth_card *card)
49804971
qeth_clean_channel(&card->write);
49814972
if (card->dev)
49824973
free_netdev(card->dev);
4983-
kfree(card->ip_tbd_list);
49844974
qeth_free_qdio_buffers(card);
49854975
unregister_service_level(&card->qeth_service_level);
49864976
kfree(card);

drivers/s390/net/qeth_l2.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,11 @@ int qeth_l2_create_device_attributes(struct device *);
1212
void qeth_l2_remove_device_attributes(struct device *);
1313
void qeth_l2_setup_bridgeport_attrs(struct qeth_card *card);
1414

15+
struct qeth_mac {
16+
u8 mac_addr[OSA_ADDR_LEN];
17+
u8 is_uc:1;
18+
u8 disp_flag:2;
19+
struct hlist_node hnode;
20+
};
21+
1522
#endif /* __QETH_L2_H__ */

drivers/s390/net/qeth_l2_main.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -780,7 +780,7 @@ qeth_l2_add_mac(struct qeth_card *card, struct netdev_hw_addr *ha, u8 is_uc)
780780
qeth_l2_mac_hash(ha->addr)) {
781781
if (is_uc == mac->is_uc &&
782782
!memcmp(ha->addr, mac->mac_addr, OSA_ADDR_LEN)) {
783-
mac->disp_flag = QETH_DISP_MAC_DO_NOTHING;
783+
mac->disp_flag = QETH_DISP_ADDR_DO_NOTHING;
784784
return;
785785
}
786786
}
@@ -792,7 +792,7 @@ qeth_l2_add_mac(struct qeth_card *card, struct netdev_hw_addr *ha, u8 is_uc)
792792

793793
memcpy(mac->mac_addr, ha->addr, OSA_ADDR_LEN);
794794
mac->is_uc = is_uc;
795-
mac->disp_flag = QETH_DISP_MAC_ADD;
795+
mac->disp_flag = QETH_DISP_ADDR_ADD;
796796

797797
hash_add(card->mac_htable, &mac->hnode,
798798
qeth_l2_mac_hash(mac->mac_addr));
@@ -825,7 +825,7 @@ static void qeth_l2_set_rx_mode(struct net_device *dev)
825825
qeth_l2_add_mac(card, ha, 1);
826826

827827
hash_for_each_safe(card->mac_htable, i, tmp, mac, hnode) {
828-
if (mac->disp_flag == QETH_DISP_MAC_DELETE) {
828+
if (mac->disp_flag == QETH_DISP_ADDR_DELETE) {
829829
if (!mac->is_uc)
830830
rc = qeth_l2_send_delgroupmac(card,
831831
mac->mac_addr);
@@ -837,15 +837,15 @@ static void qeth_l2_set_rx_mode(struct net_device *dev)
837837
hash_del(&mac->hnode);
838838
kfree(mac);
839839

840-
} else if (mac->disp_flag == QETH_DISP_MAC_ADD) {
840+
} else if (mac->disp_flag == QETH_DISP_ADDR_ADD) {
841841
rc = qeth_l2_write_mac(card, mac);
842842
if (rc) {
843843
hash_del(&mac->hnode);
844844
kfree(mac);
845845
} else
846-
mac->disp_flag = QETH_DISP_MAC_DELETE;
846+
mac->disp_flag = QETH_DISP_ADDR_DELETE;
847847
} else
848-
mac->disp_flag = QETH_DISP_MAC_DELETE;
848+
mac->disp_flag = QETH_DISP_ADDR_DELETE;
849849
}
850850

851851
spin_unlock_bh(&card->mclock);

drivers/s390/net/qeth_l3.h

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,23 @@
1010
#define __QETH_L3_H__
1111

1212
#include "qeth_core.h"
13+
#include <linux/hashtable.h>
1314

1415
#define QETH_SNIFF_AVAIL 0x0008
1516

1617
struct qeth_ipaddr {
17-
struct list_head entry;
18+
struct hlist_node hnode;
1819
enum qeth_ip_types type;
1920
enum qeth_ipa_setdelip_flags set_flags;
2021
enum qeth_ipa_setdelip_flags del_flags;
21-
int is_multicast;
22-
int users;
22+
u8 is_multicast:1;
23+
u8 in_progress:1;
24+
u8 disp_flag:2;
25+
26+
/* is changed only for normal ip addresses
27+
* for non-normal addresses it always is 1
28+
*/
29+
int ref_counter;
2330
enum qeth_prot_versions proto;
2431
unsigned char mac[OSA_ADDR_LEN];
2532
union {
@@ -32,7 +39,24 @@ struct qeth_ipaddr {
3239
unsigned int pfxlen;
3340
} a6;
3441
} u;
42+
3543
};
44+
static inline u64 qeth_l3_ipaddr_hash(struct qeth_ipaddr *addr)
45+
{
46+
u64 ret = 0;
47+
u8 *point;
48+
49+
if (addr->proto == QETH_PROT_IPV6) {
50+
point = (u8 *) &addr->u.a6.addr;
51+
ret = get_unaligned((u64 *)point) ^
52+
get_unaligned((u64 *) (point + 8));
53+
}
54+
if (addr->proto == QETH_PROT_IPV4) {
55+
point = (u8 *) &addr->u.a4.addr;
56+
ret = get_unaligned((u32 *) point);
57+
}
58+
return ret;
59+
}
3660

3761
struct qeth_ipato_entry {
3862
struct list_head entry;
@@ -60,6 +84,5 @@ int qeth_l3_is_addr_covered_by_ipato(struct qeth_card *, struct qeth_ipaddr *);
6084
struct qeth_ipaddr *qeth_l3_get_addr_buffer(enum qeth_prot_versions);
6185
int qeth_l3_add_ip(struct qeth_card *, struct qeth_ipaddr *);
6286
int qeth_l3_delete_ip(struct qeth_card *, struct qeth_ipaddr *);
63-
void qeth_l3_set_ip_addr_list(struct qeth_card *);
6487

6588
#endif /* __QETH_L3_H__ */

0 commit comments

Comments
 (0)