1922 * correct squeue down below.
1923 * But a listner close can race with processing of
1924 * incoming SYN. If incoming SYN processing changes
1925 * the squeue then the listener close which is waiting
1926 * to enter the squeue would operate on the wrong
1927 * squeue. Hence we don't change the squeue here unless
1928 * the refcount is exactly the minimum refcount. The
1929 * minimum refcount of 4 is counted as - 1 each for
1930 * TCP and IP, 1 for being in the classifier hash, and
1931 * 1 for the mblk being processed.
1932 */
1933
1934 if (connp->conn_ref != 4 ||
1935 connp->conn_tcp->tcp_state != TCPS_LISTEN) {
1936 mutex_exit(&connp->conn_lock);
1937 mutex_exit(&connp->conn_fanout->connf_lock);
1938 goto done;
1939 }
1940 if (connp->conn_sqp != new_sqp) {
1941 while (connp->conn_sqp != new_sqp)
1942 (void) casptr(&connp->conn_sqp, sqp, new_sqp);
1943 /* No special MT issues for outbound ixa_sqp hint */
1944 connp->conn_ixa->ixa_sqp = new_sqp;
1945 }
1946
1947 do {
1948 conn_flags = connp->conn_flags;
1949 conn_flags |= IPCL_FULLY_BOUND;
1950 (void) cas32(&connp->conn_flags, connp->conn_flags,
1951 conn_flags);
1952 } while (!(connp->conn_flags & IPCL_FULLY_BOUND));
1953
1954 mutex_exit(&connp->conn_fanout->connf_lock);
1955 mutex_exit(&connp->conn_lock);
1956
1957 /*
1958 * Assume we have picked a good squeue for the listener. Make
1959 * subsequent SYNs not try to change the squeue.
1960 */
1961 connp->conn_recv = tcp_input_listener;
1962 }
1963
1964 done:
1965 if (connp->conn_sqp != sqp) {
1966 CONN_INC_REF(connp);
1967 SQUEUE_ENTER_ONE(connp->conn_sqp, mp, connp->conn_recv, connp,
1968 ira, SQ_FILL, SQTAG_TCP_CONN_REQ_UNBOUND);
1969 } else {
1970 tcp_input_listener(connp, mp, sqp, ira);
1971 }
|
1922 * correct squeue down below.
1923 * But a listner close can race with processing of
1924 * incoming SYN. If incoming SYN processing changes
1925 * the squeue then the listener close which is waiting
1926 * to enter the squeue would operate on the wrong
1927 * squeue. Hence we don't change the squeue here unless
1928 * the refcount is exactly the minimum refcount. The
1929 * minimum refcount of 4 is counted as - 1 each for
1930 * TCP and IP, 1 for being in the classifier hash, and
1931 * 1 for the mblk being processed.
1932 */
1933
1934 if (connp->conn_ref != 4 ||
1935 connp->conn_tcp->tcp_state != TCPS_LISTEN) {
1936 mutex_exit(&connp->conn_lock);
1937 mutex_exit(&connp->conn_fanout->connf_lock);
1938 goto done;
1939 }
1940 if (connp->conn_sqp != new_sqp) {
1941 while (connp->conn_sqp != new_sqp)
1942 (void) atomic_cas_ptr(&connp->conn_sqp, sqp,
1943 new_sqp);
1944 /* No special MT issues for outbound ixa_sqp hint */
1945 connp->conn_ixa->ixa_sqp = new_sqp;
1946 }
1947
1948 do {
1949 conn_flags = connp->conn_flags;
1950 conn_flags |= IPCL_FULLY_BOUND;
1951 (void) atomic_cas_32(&connp->conn_flags,
1952 connp->conn_flags, conn_flags);
1953 } while (!(connp->conn_flags & IPCL_FULLY_BOUND));
1954
1955 mutex_exit(&connp->conn_fanout->connf_lock);
1956 mutex_exit(&connp->conn_lock);
1957
1958 /*
1959 * Assume we have picked a good squeue for the listener. Make
1960 * subsequent SYNs not try to change the squeue.
1961 */
1962 connp->conn_recv = tcp_input_listener;
1963 }
1964
1965 done:
1966 if (connp->conn_sqp != sqp) {
1967 CONN_INC_REF(connp);
1968 SQUEUE_ENTER_ONE(connp->conn_sqp, mp, connp->conn_recv, connp,
1969 ira, SQ_FILL, SQTAG_TCP_CONN_REQ_UNBOUND);
1970 } else {
1971 tcp_input_listener(connp, mp, sqp, ira);
1972 }
|