diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-11-25 21:30:21 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-11-25 21:30:21 -0500 |
commit | c42b4e6501cdaabee8cc292ae1ef0f66bf4825c1 (patch) | |
tree | 8ae9c4f0881891459107a226968a65a265b34134 /drivers/tty/n_gsm.c | |
parent | aebf045382edb32bd763d8edea02a559e7dc41e9 (diff) |
Revert "n_gsm: race between ld close and gsmtty open"
This reverts commit c284ee2cf12b55fa8496b2d098bf0938688f1c1c. Turns out
the locking was incorrect.
Reported-by: Fengguang Wu <fengguang.wu@intel.com>
Cc: Chao Bi <chao.bi@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty/n_gsm.c')
-rw-r--r-- | drivers/tty/n_gsm.c | 37 |
1 files changed, 10 insertions, 27 deletions
diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index 069bfd654485..c0f76da55304 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c | |||
@@ -2054,11 +2054,9 @@ void gsm_cleanup_mux(struct gsm_mux *gsm) | |||
2054 | dlci->state == DLCI_CLOSED); | 2054 | dlci->state == DLCI_CLOSED); |
2055 | } | 2055 | } |
2056 | /* Free up any link layer users */ | 2056 | /* Free up any link layer users */ |
2057 | spin_lock(&gsm->lock); | ||
2058 | for (i = 0; i < NUM_DLCI; i++) | 2057 | for (i = 0; i < NUM_DLCI; i++) |
2059 | if (gsm->dlci[i]) | 2058 | if (gsm->dlci[i]) |
2060 | gsm_dlci_release(gsm->dlci[i]); | 2059 | gsm_dlci_release(gsm->dlci[i]); |
2061 | spin_unlock(&gsm->lock); | ||
2062 | /* Now wipe the queues */ | 2060 | /* Now wipe the queues */ |
2063 | list_for_each_entry_safe(txq, ntxq, &gsm->tx_list, list) | 2061 | list_for_each_entry_safe(txq, ntxq, &gsm->tx_list, list) |
2064 | kfree(txq); | 2062 | kfree(txq); |
@@ -2911,33 +2909,23 @@ static int gsmtty_install(struct tty_driver *driver, struct tty_struct *tty) | |||
2911 | This is ok from a locking | 2909 | This is ok from a locking |
2912 | perspective as we don't have to worry about this | 2910 | perspective as we don't have to worry about this |
2913 | if DLCI0 is lost */ | 2911 | if DLCI0 is lost */ |
2914 | spin_lock(&gsm->lock); | 2912 | if (gsm->dlci[0] && gsm->dlci[0]->state != DLCI_OPEN) |
2915 | if (gsm->dlci[0] && gsm->dlci[0]->state != DLCI_OPEN) { | ||
2916 | spin_unlock(&gsm->lock); | ||
2917 | return -EL2NSYNC; | 2913 | return -EL2NSYNC; |
2918 | } | ||
2919 | dlci = gsm->dlci[line]; | 2914 | dlci = gsm->dlci[line]; |
2920 | if (dlci == NULL) { | 2915 | if (dlci == NULL) { |
2921 | alloc = true; | 2916 | alloc = true; |
2922 | dlci = gsm_dlci_alloc(gsm, line); | 2917 | dlci = gsm_dlci_alloc(gsm, line); |
2923 | } | 2918 | } |
2924 | if (dlci == NULL) { | 2919 | if (dlci == NULL) |
2925 | spin_unlock(&gsm->lock); | ||
2926 | return -ENOMEM; | 2920 | return -ENOMEM; |
2927 | } | ||
2928 | ret = tty_port_install(&dlci->port, driver, tty); | 2921 | ret = tty_port_install(&dlci->port, driver, tty); |
2929 | if (ret) { | 2922 | if (ret) { |
2930 | if (alloc) | 2923 | if (alloc) |
2931 | dlci_put(dlci); | 2924 | dlci_put(dlci); |
2932 | spin_unlock(&gsm->lock); | ||
2933 | return ret; | 2925 | return ret; |
2934 | } | 2926 | } |
2935 | 2927 | ||
2936 | dlci_get(dlci); | ||
2937 | dlci_get(gsm->dlci[0]); | ||
2938 | mux_get(gsm); | ||
2939 | tty->driver_data = dlci; | 2928 | tty->driver_data = dlci; |
2940 | spin_unlock(&gsm->lock); | ||
2941 | 2929 | ||
2942 | return 0; | 2930 | return 0; |
2943 | } | 2931 | } |
@@ -2948,6 +2936,9 @@ static int gsmtty_open(struct tty_struct *tty, struct file *filp) | |||
2948 | struct tty_port *port = &dlci->port; | 2936 | struct tty_port *port = &dlci->port; |
2949 | 2937 | ||
2950 | port->count++; | 2938 | port->count++; |
2939 | dlci_get(dlci); | ||
2940 | dlci_get(dlci->gsm->dlci[0]); | ||
2941 | mux_get(dlci->gsm); | ||
2951 | tty_port_tty_set(port, tty); | 2942 | tty_port_tty_set(port, tty); |
2952 | 2943 | ||
2953 | dlci->modem_rx = 0; | 2944 | dlci->modem_rx = 0; |
@@ -2974,7 +2965,7 @@ static void gsmtty_close(struct tty_struct *tty, struct file *filp) | |||
2974 | mutex_unlock(&dlci->mutex); | 2965 | mutex_unlock(&dlci->mutex); |
2975 | gsm = dlci->gsm; | 2966 | gsm = dlci->gsm; |
2976 | if (tty_port_close_start(&dlci->port, tty, filp) == 0) | 2967 | if (tty_port_close_start(&dlci->port, tty, filp) == 0) |
2977 | return; | 2968 | goto out; |
2978 | gsm_dlci_begin_close(dlci); | 2969 | gsm_dlci_begin_close(dlci); |
2979 | if (test_bit(ASYNCB_INITIALIZED, &dlci->port.flags)) { | 2970 | if (test_bit(ASYNCB_INITIALIZED, &dlci->port.flags)) { |
2980 | if (C_HUPCL(tty)) | 2971 | if (C_HUPCL(tty)) |
@@ -2982,7 +2973,10 @@ static void gsmtty_close(struct tty_struct *tty, struct file *filp) | |||
2982 | } | 2973 | } |
2983 | tty_port_close_end(&dlci->port, tty); | 2974 | tty_port_close_end(&dlci->port, tty); |
2984 | tty_port_tty_set(&dlci->port, NULL); | 2975 | tty_port_tty_set(&dlci->port, NULL); |
2985 | return; | 2976 | out: |
2977 | dlci_put(dlci); | ||
2978 | dlci_put(gsm->dlci[0]); | ||
2979 | mux_put(gsm); | ||
2986 | } | 2980 | } |
2987 | 2981 | ||
2988 | static void gsmtty_hangup(struct tty_struct *tty) | 2982 | static void gsmtty_hangup(struct tty_struct *tty) |
@@ -3159,16 +3153,6 @@ static int gsmtty_break_ctl(struct tty_struct *tty, int state) | |||
3159 | return gsmtty_modem_update(dlci, encode); | 3153 | return gsmtty_modem_update(dlci, encode); |
3160 | } | 3154 | } |
3161 | 3155 | ||
3162 | static void gsmtty_remove(struct tty_driver *driver, struct tty_struct *tty) | ||
3163 | { | ||
3164 | struct gsm_dlci *dlci = tty->driver_data; | ||
3165 | struct gsm_mux *gsm = dlci->gsm; | ||
3166 | |||
3167 | dlci_put(dlci); | ||
3168 | dlci_put(gsm->dlci[0]); | ||
3169 | mux_put(gsm); | ||
3170 | driver->ttys[tty->index] = NULL; | ||
3171 | } | ||
3172 | 3156 | ||
3173 | /* Virtual ttys for the demux */ | 3157 | /* Virtual ttys for the demux */ |
3174 | static const struct tty_operations gsmtty_ops = { | 3158 | static const struct tty_operations gsmtty_ops = { |
@@ -3188,7 +3172,6 @@ static const struct tty_operations gsmtty_ops = { | |||
3188 | .tiocmget = gsmtty_tiocmget, | 3172 | .tiocmget = gsmtty_tiocmget, |
3189 | .tiocmset = gsmtty_tiocmset, | 3173 | .tiocmset = gsmtty_tiocmset, |
3190 | .break_ctl = gsmtty_break_ctl, | 3174 | .break_ctl = gsmtty_break_ctl, |
3191 | .remove = gsmtty_remove, | ||
3192 | }; | 3175 | }; |
3193 | 3176 | ||
3194 | 3177 | ||