diff options
author | Ursula Braun <ursula.braun@de.ibm.com> | 2010-07-22 19:15:05 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-07-23 15:36:23 -0400 |
commit | 9dc48ccc68b9dfc01c2beee2d4317fb3df3fdce9 (patch) | |
tree | 83d101e637385276ca40af1bb70ecc14ab24e33f | |
parent | 75e0de13631e115768a97131a2d7f5259217512d (diff) |
qeth: serialize sysfs-triggered device configurations
This patch serializes device removal and other sysfs-triggered
configurations by moving removal of sysfs-attributes to the beginning
of the remove functions. And it serializes online/offline setting
and discipline-switching (causing reestablishing of the net_device)
by making use of a new discipline mutex.
Signed-off-by: Ursula Braun <ursula.braun@de.ibm.com>
Signed-off-by: Frank Blaschka <frank.blaschka@de.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/s390/net/qeth_core.h | 1 | ||||
-rw-r--r-- | drivers/s390/net/qeth_core_main.c | 11 | ||||
-rw-r--r-- | drivers/s390/net/qeth_core_sys.c | 4 | ||||
-rw-r--r-- | drivers/s390/net/qeth_l2_main.c | 5 | ||||
-rw-r--r-- | drivers/s390/net/qeth_l3_main.c | 8 |
5 files changed, 22 insertions, 7 deletions
diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h index e7e99e6cad21..41ddf86c3421 100644 --- a/drivers/s390/net/qeth_core.h +++ b/drivers/s390/net/qeth_core.h | |||
@@ -747,6 +747,7 @@ struct qeth_card { | |||
747 | struct qdio_ssqd_desc ssqd; | 747 | struct qdio_ssqd_desc ssqd; |
748 | debug_info_t *debug; | 748 | debug_info_t *debug; |
749 | struct mutex conf_mutex; | 749 | struct mutex conf_mutex; |
750 | struct mutex discipline_mutex; | ||
750 | }; | 751 | }; |
751 | 752 | ||
752 | struct qeth_card_list_struct { | 753 | struct qeth_card_list_struct { |
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index 844935fbe6a8..f33da45c35ef 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c | |||
@@ -1084,6 +1084,7 @@ static int qeth_setup_card(struct qeth_card *card) | |||
1084 | spin_lock_init(&card->ip_lock); | 1084 | spin_lock_init(&card->ip_lock); |
1085 | spin_lock_init(&card->thread_mask_lock); | 1085 | spin_lock_init(&card->thread_mask_lock); |
1086 | mutex_init(&card->conf_mutex); | 1086 | mutex_init(&card->conf_mutex); |
1087 | mutex_init(&card->discipline_mutex); | ||
1087 | card->thread_start_mask = 0; | 1088 | card->thread_start_mask = 0; |
1088 | card->thread_allowed_mask = 0; | 1089 | card->thread_allowed_mask = 0; |
1089 | card->thread_running_mask = 0; | 1090 | card->thread_running_mask = 0; |
@@ -4348,16 +4349,18 @@ static void qeth_core_remove_device(struct ccwgroup_device *gdev) | |||
4348 | struct qeth_card *card = dev_get_drvdata(&gdev->dev); | 4349 | struct qeth_card *card = dev_get_drvdata(&gdev->dev); |
4349 | 4350 | ||
4350 | QETH_DBF_TEXT(SETUP, 2, "removedv"); | 4351 | QETH_DBF_TEXT(SETUP, 2, "removedv"); |
4351 | if (card->discipline.ccwgdriver) { | ||
4352 | card->discipline.ccwgdriver->remove(gdev); | ||
4353 | qeth_core_free_discipline(card); | ||
4354 | } | ||
4355 | 4352 | ||
4356 | if (card->info.type == QETH_CARD_TYPE_OSN) { | 4353 | if (card->info.type == QETH_CARD_TYPE_OSN) { |
4357 | qeth_core_remove_osn_attributes(&gdev->dev); | 4354 | qeth_core_remove_osn_attributes(&gdev->dev); |
4358 | } else { | 4355 | } else { |
4359 | qeth_core_remove_device_attributes(&gdev->dev); | 4356 | qeth_core_remove_device_attributes(&gdev->dev); |
4360 | } | 4357 | } |
4358 | |||
4359 | if (card->discipline.ccwgdriver) { | ||
4360 | card->discipline.ccwgdriver->remove(gdev); | ||
4361 | qeth_core_free_discipline(card); | ||
4362 | } | ||
4363 | |||
4361 | debug_unregister(card->debug); | 4364 | debug_unregister(card->debug); |
4362 | write_lock_irqsave(&qeth_core_card_list.rwlock, flags); | 4365 | write_lock_irqsave(&qeth_core_card_list.rwlock, flags); |
4363 | list_del(&card->list); | 4366 | list_del(&card->list); |
diff --git a/drivers/s390/net/qeth_core_sys.c b/drivers/s390/net/qeth_core_sys.c index 6b7fd88e8e4d..42fa783a70c8 100644 --- a/drivers/s390/net/qeth_core_sys.c +++ b/drivers/s390/net/qeth_core_sys.c | |||
@@ -411,7 +411,7 @@ static ssize_t qeth_dev_layer2_store(struct device *dev, | |||
411 | if (!card) | 411 | if (!card) |
412 | return -EINVAL; | 412 | return -EINVAL; |
413 | 413 | ||
414 | mutex_lock(&card->conf_mutex); | 414 | mutex_lock(&card->discipline_mutex); |
415 | if (card->state != CARD_STATE_DOWN) { | 415 | if (card->state != CARD_STATE_DOWN) { |
416 | rc = -EPERM; | 416 | rc = -EPERM; |
417 | goto out; | 417 | goto out; |
@@ -446,7 +446,7 @@ static ssize_t qeth_dev_layer2_store(struct device *dev, | |||
446 | 446 | ||
447 | rc = card->discipline.ccwgdriver->probe(card->gdev); | 447 | rc = card->discipline.ccwgdriver->probe(card->gdev); |
448 | out: | 448 | out: |
449 | mutex_unlock(&card->conf_mutex); | 449 | mutex_unlock(&card->discipline_mutex); |
450 | return rc ? rc : count; | 450 | return rc ? rc : count; |
451 | } | 451 | } |
452 | 452 | ||
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index 32d07c2dcc67..5e66333a8bea 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c | |||
@@ -935,6 +935,7 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode) | |||
935 | enum qeth_card_states recover_flag; | 935 | enum qeth_card_states recover_flag; |
936 | 936 | ||
937 | BUG_ON(!card); | 937 | BUG_ON(!card); |
938 | mutex_lock(&card->discipline_mutex); | ||
938 | mutex_lock(&card->conf_mutex); | 939 | mutex_lock(&card->conf_mutex); |
939 | QETH_DBF_TEXT(SETUP, 2, "setonlin"); | 940 | QETH_DBF_TEXT(SETUP, 2, "setonlin"); |
940 | QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *)); | 941 | QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *)); |
@@ -1012,6 +1013,7 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode) | |||
1012 | kobject_uevent(&gdev->dev.kobj, KOBJ_CHANGE); | 1013 | kobject_uevent(&gdev->dev.kobj, KOBJ_CHANGE); |
1013 | out: | 1014 | out: |
1014 | mutex_unlock(&card->conf_mutex); | 1015 | mutex_unlock(&card->conf_mutex); |
1016 | mutex_unlock(&card->discipline_mutex); | ||
1015 | return 0; | 1017 | return 0; |
1016 | 1018 | ||
1017 | out_remove: | 1019 | out_remove: |
@@ -1025,6 +1027,7 @@ out_remove: | |||
1025 | else | 1027 | else |
1026 | card->state = CARD_STATE_DOWN; | 1028 | card->state = CARD_STATE_DOWN; |
1027 | mutex_unlock(&card->conf_mutex); | 1029 | mutex_unlock(&card->conf_mutex); |
1030 | mutex_unlock(&card->discipline_mutex); | ||
1028 | return rc; | 1031 | return rc; |
1029 | } | 1032 | } |
1030 | 1033 | ||
@@ -1040,6 +1043,7 @@ static int __qeth_l2_set_offline(struct ccwgroup_device *cgdev, | |||
1040 | int rc = 0, rc2 = 0, rc3 = 0; | 1043 | int rc = 0, rc2 = 0, rc3 = 0; |
1041 | enum qeth_card_states recover_flag; | 1044 | enum qeth_card_states recover_flag; |
1042 | 1045 | ||
1046 | mutex_lock(&card->discipline_mutex); | ||
1043 | mutex_lock(&card->conf_mutex); | 1047 | mutex_lock(&card->conf_mutex); |
1044 | QETH_DBF_TEXT(SETUP, 3, "setoffl"); | 1048 | QETH_DBF_TEXT(SETUP, 3, "setoffl"); |
1045 | QETH_DBF_HEX(SETUP, 3, &card, sizeof(void *)); | 1049 | QETH_DBF_HEX(SETUP, 3, &card, sizeof(void *)); |
@@ -1060,6 +1064,7 @@ static int __qeth_l2_set_offline(struct ccwgroup_device *cgdev, | |||
1060 | /* let user_space know that device is offline */ | 1064 | /* let user_space know that device is offline */ |
1061 | kobject_uevent(&cgdev->dev.kobj, KOBJ_CHANGE); | 1065 | kobject_uevent(&cgdev->dev.kobj, KOBJ_CHANGE); |
1062 | mutex_unlock(&card->conf_mutex); | 1066 | mutex_unlock(&card->conf_mutex); |
1067 | mutex_unlock(&card->discipline_mutex); | ||
1063 | return 0; | 1068 | return 0; |
1064 | } | 1069 | } |
1065 | 1070 | ||
diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index 15b5ca82bd26..e22ae248f613 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c | |||
@@ -3354,6 +3354,8 @@ static void qeth_l3_remove_device(struct ccwgroup_device *cgdev) | |||
3354 | { | 3354 | { |
3355 | struct qeth_card *card = dev_get_drvdata(&cgdev->dev); | 3355 | struct qeth_card *card = dev_get_drvdata(&cgdev->dev); |
3356 | 3356 | ||
3357 | qeth_l3_remove_device_attributes(&cgdev->dev); | ||
3358 | |||
3357 | qeth_set_allowed_threads(card, 0, 1); | 3359 | qeth_set_allowed_threads(card, 0, 1); |
3358 | wait_event(card->wait_q, qeth_threads_running(card, 0xffffffff) == 0); | 3360 | wait_event(card->wait_q, qeth_threads_running(card, 0xffffffff) == 0); |
3359 | 3361 | ||
@@ -3367,7 +3369,6 @@ static void qeth_l3_remove_device(struct ccwgroup_device *cgdev) | |||
3367 | card->dev = NULL; | 3369 | card->dev = NULL; |
3368 | } | 3370 | } |
3369 | 3371 | ||
3370 | qeth_l3_remove_device_attributes(&cgdev->dev); | ||
3371 | qeth_l3_clear_ip_list(card, 0, 0); | 3372 | qeth_l3_clear_ip_list(card, 0, 0); |
3372 | qeth_l3_clear_ipato_list(card); | 3373 | qeth_l3_clear_ipato_list(card); |
3373 | return; | 3374 | return; |
@@ -3380,6 +3381,7 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode) | |||
3380 | enum qeth_card_states recover_flag; | 3381 | enum qeth_card_states recover_flag; |
3381 | 3382 | ||
3382 | BUG_ON(!card); | 3383 | BUG_ON(!card); |
3384 | mutex_lock(&card->discipline_mutex); | ||
3383 | mutex_lock(&card->conf_mutex); | 3385 | mutex_lock(&card->conf_mutex); |
3384 | QETH_DBF_TEXT(SETUP, 2, "setonlin"); | 3386 | QETH_DBF_TEXT(SETUP, 2, "setonlin"); |
3385 | QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *)); | 3387 | QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *)); |
@@ -3461,6 +3463,7 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode) | |||
3461 | kobject_uevent(&gdev->dev.kobj, KOBJ_CHANGE); | 3463 | kobject_uevent(&gdev->dev.kobj, KOBJ_CHANGE); |
3462 | out: | 3464 | out: |
3463 | mutex_unlock(&card->conf_mutex); | 3465 | mutex_unlock(&card->conf_mutex); |
3466 | mutex_unlock(&card->discipline_mutex); | ||
3464 | return 0; | 3467 | return 0; |
3465 | out_remove: | 3468 | out_remove: |
3466 | card->use_hard_stop = 1; | 3469 | card->use_hard_stop = 1; |
@@ -3473,6 +3476,7 @@ out_remove: | |||
3473 | else | 3476 | else |
3474 | card->state = CARD_STATE_DOWN; | 3477 | card->state = CARD_STATE_DOWN; |
3475 | mutex_unlock(&card->conf_mutex); | 3478 | mutex_unlock(&card->conf_mutex); |
3479 | mutex_unlock(&card->discipline_mutex); | ||
3476 | return rc; | 3480 | return rc; |
3477 | } | 3481 | } |
3478 | 3482 | ||
@@ -3488,6 +3492,7 @@ static int __qeth_l3_set_offline(struct ccwgroup_device *cgdev, | |||
3488 | int rc = 0, rc2 = 0, rc3 = 0; | 3492 | int rc = 0, rc2 = 0, rc3 = 0; |
3489 | enum qeth_card_states recover_flag; | 3493 | enum qeth_card_states recover_flag; |
3490 | 3494 | ||
3495 | mutex_lock(&card->discipline_mutex); | ||
3491 | mutex_lock(&card->conf_mutex); | 3496 | mutex_lock(&card->conf_mutex); |
3492 | QETH_DBF_TEXT(SETUP, 3, "setoffl"); | 3497 | QETH_DBF_TEXT(SETUP, 3, "setoffl"); |
3493 | QETH_DBF_HEX(SETUP, 3, &card, sizeof(void *)); | 3498 | QETH_DBF_HEX(SETUP, 3, &card, sizeof(void *)); |
@@ -3508,6 +3513,7 @@ static int __qeth_l3_set_offline(struct ccwgroup_device *cgdev, | |||
3508 | /* let user_space know that device is offline */ | 3513 | /* let user_space know that device is offline */ |
3509 | kobject_uevent(&cgdev->dev.kobj, KOBJ_CHANGE); | 3514 | kobject_uevent(&cgdev->dev.kobj, KOBJ_CHANGE); |
3510 | mutex_unlock(&card->conf_mutex); | 3515 | mutex_unlock(&card->conf_mutex); |
3516 | mutex_unlock(&card->discipline_mutex); | ||
3511 | return 0; | 3517 | return 0; |
3512 | } | 3518 | } |
3513 | 3519 | ||