aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/sgi-xp/xpc_sn2.c
diff options
context:
space:
mode:
authorDean Nelson <dcn@sgi.com>2008-07-30 01:34:19 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-07-30 12:41:50 -0400
commitbd3e64c1759e4930315ebf022611468ee9621486 (patch)
tree314f4f8a80788b181aa03714d952854c8e2a1866 /drivers/misc/sgi-xp/xpc_sn2.c
parent5b8669dfd110a62a74eea525a009342f73987ea0 (diff)
sgi-xp: setup the notify GRU message queue
Setup the notify GRU message queue that is used for sending user messages on UV systems. Signed-off-by: Dean Nelson <dcn@sgi.com> Cc: Jack Steiner <steiner@sgi.com> Cc: "Luck, Tony" <tony.luck@intel.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/misc/sgi-xp/xpc_sn2.c')
-rw-r--r--drivers/misc/sgi-xp/xpc_sn2.c178
1 files changed, 96 insertions, 82 deletions
diff --git a/drivers/misc/sgi-xp/xpc_sn2.c b/drivers/misc/sgi-xp/xpc_sn2.c
index 8b4b0653d9e9..b4882ccf6344 100644
--- a/drivers/misc/sgi-xp/xpc_sn2.c
+++ b/drivers/misc/sgi-xp/xpc_sn2.c
@@ -408,7 +408,7 @@ xpc_send_chctl_openrequest_sn2(struct xpc_channel *ch, unsigned long *irq_flags)
408{ 408{
409 struct xpc_openclose_args *args = ch->sn.sn2.local_openclose_args; 409 struct xpc_openclose_args *args = ch->sn.sn2.local_openclose_args;
410 410
411 args->msg_size = ch->msg_size; 411 args->entry_size = ch->entry_size;
412 args->local_nentries = ch->local_nentries; 412 args->local_nentries = ch->local_nentries;
413 XPC_SEND_NOTIFY_IRQ_SN2(ch, XPC_CHCTL_OPENREQUEST, irq_flags); 413 XPC_SEND_NOTIFY_IRQ_SN2(ch, XPC_CHCTL_OPENREQUEST, irq_flags);
414} 414}
@@ -1531,14 +1531,14 @@ xpc_allocate_local_msgqueue_sn2(struct xpc_channel *ch)
1531 1531
1532 for (nentries = ch->local_nentries; nentries > 0; nentries--) { 1532 for (nentries = ch->local_nentries; nentries > 0; nentries--) {
1533 1533
1534 nbytes = nentries * ch->msg_size; 1534 nbytes = nentries * ch->entry_size;
1535 ch_sn2->local_msgqueue = 1535 ch_sn2->local_msgqueue =
1536 xpc_kzalloc_cacheline_aligned(nbytes, GFP_KERNEL, 1536 xpc_kzalloc_cacheline_aligned(nbytes, GFP_KERNEL,
1537 &ch_sn2->local_msgqueue_base); 1537 &ch_sn2->local_msgqueue_base);
1538 if (ch_sn2->local_msgqueue == NULL) 1538 if (ch_sn2->local_msgqueue == NULL)
1539 continue; 1539 continue;
1540 1540
1541 nbytes = nentries * sizeof(struct xpc_notify); 1541 nbytes = nentries * sizeof(struct xpc_notify_sn2);
1542 ch_sn2->notify_queue = kzalloc(nbytes, GFP_KERNEL); 1542 ch_sn2->notify_queue = kzalloc(nbytes, GFP_KERNEL);
1543 if (ch_sn2->notify_queue == NULL) { 1543 if (ch_sn2->notify_queue == NULL) {
1544 kfree(ch_sn2->local_msgqueue_base); 1544 kfree(ch_sn2->local_msgqueue_base);
@@ -1578,7 +1578,7 @@ xpc_allocate_remote_msgqueue_sn2(struct xpc_channel *ch)
1578 1578
1579 for (nentries = ch->remote_nentries; nentries > 0; nentries--) { 1579 for (nentries = ch->remote_nentries; nentries > 0; nentries--) {
1580 1580
1581 nbytes = nentries * ch->msg_size; 1581 nbytes = nentries * ch->entry_size;
1582 ch_sn2->remote_msgqueue = 1582 ch_sn2->remote_msgqueue =
1583 xpc_kzalloc_cacheline_aligned(nbytes, GFP_KERNEL, &ch_sn2-> 1583 xpc_kzalloc_cacheline_aligned(nbytes, GFP_KERNEL, &ch_sn2->
1584 remote_msgqueue_base); 1584 remote_msgqueue_base);
@@ -1632,9 +1632,6 @@ xpc_setup_msg_structures_sn2(struct xpc_channel *ch)
1632/* 1632/*
1633 * Free up message queues and other stuff that were allocated for the specified 1633 * Free up message queues and other stuff that were allocated for the specified
1634 * channel. 1634 * channel.
1635 *
1636 * Note: ch->reason and ch->reason_line are left set for debugging purposes,
1637 * they're cleared when XPC_C_DISCONNECTED is cleared.
1638 */ 1635 */
1639static void 1636static void
1640xpc_teardown_msg_structures_sn2(struct xpc_channel *ch) 1637xpc_teardown_msg_structures_sn2(struct xpc_channel *ch)
@@ -1674,7 +1671,7 @@ xpc_teardown_msg_structures_sn2(struct xpc_channel *ch)
1674static void 1671static void
1675xpc_notify_senders_sn2(struct xpc_channel *ch, enum xp_retval reason, s64 put) 1672xpc_notify_senders_sn2(struct xpc_channel *ch, enum xp_retval reason, s64 put)
1676{ 1673{
1677 struct xpc_notify *notify; 1674 struct xpc_notify_sn2 *notify;
1678 u8 notify_type; 1675 u8 notify_type;
1679 s64 get = ch->sn.sn2.w_remote_GP.get - 1; 1676 s64 get = ch->sn.sn2.w_remote_GP.get - 1;
1680 1677
@@ -1699,17 +1696,16 @@ xpc_notify_senders_sn2(struct xpc_channel *ch, enum xp_retval reason, s64 put)
1699 atomic_dec(&ch->n_to_notify); 1696 atomic_dec(&ch->n_to_notify);
1700 1697
1701 if (notify->func != NULL) { 1698 if (notify->func != NULL) {
1702 dev_dbg(xpc_chan, "notify->func() called, notify=0x%p, " 1699 dev_dbg(xpc_chan, "notify->func() called, notify=0x%p "
1703 "msg_number=%ld, partid=%d, channel=%d\n", 1700 "msg_number=%ld partid=%d channel=%d\n",
1704 (void *)notify, get, ch->partid, ch->number); 1701 (void *)notify, get, ch->partid, ch->number);
1705 1702
1706 notify->func(reason, ch->partid, ch->number, 1703 notify->func(reason, ch->partid, ch->number,
1707 notify->key); 1704 notify->key);
1708 1705
1709 dev_dbg(xpc_chan, "notify->func() returned, " 1706 dev_dbg(xpc_chan, "notify->func() returned, notify=0x%p"
1710 "notify=0x%p, msg_number=%ld, partid=%d, " 1707 " msg_number=%ld partid=%d channel=%d\n",
1711 "channel=%d\n", (void *)notify, get, 1708 (void *)notify, get, ch->partid, ch->number);
1712 ch->partid, ch->number);
1713 } 1709 }
1714 } 1710 }
1715} 1711}
@@ -1727,14 +1723,14 @@ static inline void
1727xpc_clear_local_msgqueue_flags_sn2(struct xpc_channel *ch) 1723xpc_clear_local_msgqueue_flags_sn2(struct xpc_channel *ch)
1728{ 1724{
1729 struct xpc_channel_sn2 *ch_sn2 = &ch->sn.sn2; 1725 struct xpc_channel_sn2 *ch_sn2 = &ch->sn.sn2;
1730 struct xpc_msg *msg; 1726 struct xpc_msg_sn2 *msg;
1731 s64 get; 1727 s64 get;
1732 1728
1733 get = ch_sn2->w_remote_GP.get; 1729 get = ch_sn2->w_remote_GP.get;
1734 do { 1730 do {
1735 msg = (struct xpc_msg *)((u64)ch_sn2->local_msgqueue + 1731 msg = (struct xpc_msg_sn2 *)((u64)ch_sn2->local_msgqueue +
1736 (get % ch->local_nentries) * 1732 (get % ch->local_nentries) *
1737 ch->msg_size); 1733 ch->entry_size);
1738 msg->flags = 0; 1734 msg->flags = 0;
1739 } while (++get < ch_sn2->remote_GP.get); 1735 } while (++get < ch_sn2->remote_GP.get);
1740} 1736}
@@ -1746,24 +1742,30 @@ static inline void
1746xpc_clear_remote_msgqueue_flags_sn2(struct xpc_channel *ch) 1742xpc_clear_remote_msgqueue_flags_sn2(struct xpc_channel *ch)
1747{ 1743{
1748 struct xpc_channel_sn2 *ch_sn2 = &ch->sn.sn2; 1744 struct xpc_channel_sn2 *ch_sn2 = &ch->sn.sn2;
1749 struct xpc_msg *msg; 1745 struct xpc_msg_sn2 *msg;
1750 s64 put; 1746 s64 put;
1751 1747
1752 put = ch_sn2->w_remote_GP.put; 1748 put = ch_sn2->w_remote_GP.put;
1753 do { 1749 do {
1754 msg = (struct xpc_msg *)((u64)ch_sn2->remote_msgqueue + 1750 msg = (struct xpc_msg_sn2 *)((u64)ch_sn2->remote_msgqueue +
1755 (put % ch->remote_nentries) * 1751 (put % ch->remote_nentries) *
1756 ch->msg_size); 1752 ch->entry_size);
1757 msg->flags = 0; 1753 msg->flags = 0;
1758 } while (++put < ch_sn2->remote_GP.put); 1754 } while (++put < ch_sn2->remote_GP.put);
1759} 1755}
1760 1756
1757static int
1758xpc_n_of_deliverable_payloads_sn2(struct xpc_channel *ch)
1759{
1760 return ch->sn.sn2.w_remote_GP.put - ch->sn.sn2.w_local_GP.get;
1761}
1762
1761static void 1763static void
1762xpc_process_msg_chctl_flags_sn2(struct xpc_partition *part, int ch_number) 1764xpc_process_msg_chctl_flags_sn2(struct xpc_partition *part, int ch_number)
1763{ 1765{
1764 struct xpc_channel *ch = &part->channels[ch_number]; 1766 struct xpc_channel *ch = &part->channels[ch_number];
1765 struct xpc_channel_sn2 *ch_sn2 = &ch->sn.sn2; 1767 struct xpc_channel_sn2 *ch_sn2 = &ch->sn.sn2;
1766 int nmsgs_sent; 1768 int npayloads_sent;
1767 1769
1768 ch_sn2->remote_GP = part->sn.sn2.remote_GPs[ch_number]; 1770 ch_sn2->remote_GP = part->sn.sn2.remote_GPs[ch_number];
1769 1771
@@ -1835,7 +1837,7 @@ xpc_process_msg_chctl_flags_sn2(struct xpc_partition *part, int ch_number)
1835 if (ch_sn2->w_remote_GP.put != ch_sn2->remote_GP.put) { 1837 if (ch_sn2->w_remote_GP.put != ch_sn2->remote_GP.put) {
1836 /* 1838 /*
1837 * Clear msg->flags in previously received messages, so that 1839 * Clear msg->flags in previously received messages, so that
1838 * they're ready for xpc_get_deliverable_msg(). 1840 * they're ready for xpc_get_deliverable_payload_sn2().
1839 */ 1841 */
1840 xpc_clear_remote_msgqueue_flags_sn2(ch); 1842 xpc_clear_remote_msgqueue_flags_sn2(ch);
1841 1843
@@ -1845,27 +1847,27 @@ xpc_process_msg_chctl_flags_sn2(struct xpc_partition *part, int ch_number)
1845 "channel=%d\n", ch_sn2->w_remote_GP.put, ch->partid, 1847 "channel=%d\n", ch_sn2->w_remote_GP.put, ch->partid,
1846 ch->number); 1848 ch->number);
1847 1849
1848 nmsgs_sent = ch_sn2->w_remote_GP.put - ch_sn2->w_local_GP.get; 1850 npayloads_sent = xpc_n_of_deliverable_payloads_sn2(ch);
1849 if (nmsgs_sent > 0) { 1851 if (npayloads_sent > 0) {
1850 dev_dbg(xpc_chan, "msgs waiting to be copied and " 1852 dev_dbg(xpc_chan, "msgs waiting to be copied and "
1851 "delivered=%d, partid=%d, channel=%d\n", 1853 "delivered=%d, partid=%d, channel=%d\n",
1852 nmsgs_sent, ch->partid, ch->number); 1854 npayloads_sent, ch->partid, ch->number);
1853 1855
1854 if (ch->flags & XPC_C_CONNECTEDCALLOUT_MADE) 1856 if (ch->flags & XPC_C_CONNECTEDCALLOUT_MADE)
1855 xpc_activate_kthreads(ch, nmsgs_sent); 1857 xpc_activate_kthreads(ch, npayloads_sent);
1856 } 1858 }
1857 } 1859 }
1858 1860
1859 xpc_msgqueue_deref(ch); 1861 xpc_msgqueue_deref(ch);
1860} 1862}
1861 1863
1862static struct xpc_msg * 1864static struct xpc_msg_sn2 *
1863xpc_pull_remote_msg_sn2(struct xpc_channel *ch, s64 get) 1865xpc_pull_remote_msg_sn2(struct xpc_channel *ch, s64 get)
1864{ 1866{
1865 struct xpc_partition *part = &xpc_partitions[ch->partid]; 1867 struct xpc_partition *part = &xpc_partitions[ch->partid];
1866 struct xpc_channel_sn2 *ch_sn2 = &ch->sn.sn2; 1868 struct xpc_channel_sn2 *ch_sn2 = &ch->sn.sn2;
1867 unsigned long remote_msg_pa; 1869 unsigned long remote_msg_pa;
1868 struct xpc_msg *msg; 1870 struct xpc_msg_sn2 *msg;
1869 u32 msg_index; 1871 u32 msg_index;
1870 u32 nmsgs; 1872 u32 nmsgs;
1871 u64 msg_offset; 1873 u64 msg_offset;
@@ -1889,13 +1891,13 @@ xpc_pull_remote_msg_sn2(struct xpc_channel *ch, s64 get)
1889 nmsgs = ch->remote_nentries - msg_index; 1891 nmsgs = ch->remote_nentries - msg_index;
1890 } 1892 }
1891 1893
1892 msg_offset = msg_index * ch->msg_size; 1894 msg_offset = msg_index * ch->entry_size;
1893 msg = (struct xpc_msg *)((u64)ch_sn2->remote_msgqueue + 1895 msg = (struct xpc_msg_sn2 *)((u64)ch_sn2->remote_msgqueue +
1894 msg_offset); 1896 msg_offset);
1895 remote_msg_pa = ch_sn2->remote_msgqueue_pa + msg_offset; 1897 remote_msg_pa = ch_sn2->remote_msgqueue_pa + msg_offset;
1896 1898
1897 ret = xpc_pull_remote_cachelines_sn2(part, msg, remote_msg_pa, 1899 ret = xpc_pull_remote_cachelines_sn2(part, msg, remote_msg_pa,
1898 nmsgs * ch->msg_size); 1900 nmsgs * ch->entry_size);
1899 if (ret != xpSuccess) { 1901 if (ret != xpSuccess) {
1900 1902
1901 dev_dbg(xpc_chan, "failed to pull %d msgs starting with" 1903 dev_dbg(xpc_chan, "failed to pull %d msgs starting with"
@@ -1915,26 +1917,21 @@ xpc_pull_remote_msg_sn2(struct xpc_channel *ch, s64 get)
1915 mutex_unlock(&ch_sn2->msg_to_pull_mutex); 1917 mutex_unlock(&ch_sn2->msg_to_pull_mutex);
1916 1918
1917 /* return the message we were looking for */ 1919 /* return the message we were looking for */
1918 msg_offset = (get % ch->remote_nentries) * ch->msg_size; 1920 msg_offset = (get % ch->remote_nentries) * ch->entry_size;
1919 msg = (struct xpc_msg *)((u64)ch_sn2->remote_msgqueue + msg_offset); 1921 msg = (struct xpc_msg_sn2 *)((u64)ch_sn2->remote_msgqueue + msg_offset);
1920 1922
1921 return msg; 1923 return msg;
1922} 1924}
1923 1925
1924static int
1925xpc_n_of_deliverable_msgs_sn2(struct xpc_channel *ch)
1926{
1927 return ch->sn.sn2.w_remote_GP.put - ch->sn.sn2.w_local_GP.get;
1928}
1929
1930/* 1926/*
1931 * Get a message to be delivered. 1927 * Get the next deliverable message's payload.
1932 */ 1928 */
1933static struct xpc_msg * 1929static void *
1934xpc_get_deliverable_msg_sn2(struct xpc_channel *ch) 1930xpc_get_deliverable_payload_sn2(struct xpc_channel *ch)
1935{ 1931{
1936 struct xpc_channel_sn2 *ch_sn2 = &ch->sn.sn2; 1932 struct xpc_channel_sn2 *ch_sn2 = &ch->sn.sn2;
1937 struct xpc_msg *msg = NULL; 1933 struct xpc_msg_sn2 *msg;
1934 void *payload = NULL;
1938 s64 get; 1935 s64 get;
1939 1936
1940 do { 1937 do {
@@ -1965,15 +1962,16 @@ xpc_get_deliverable_msg_sn2(struct xpc_channel *ch)
1965 msg = xpc_pull_remote_msg_sn2(ch, get); 1962 msg = xpc_pull_remote_msg_sn2(ch, get);
1966 1963
1967 DBUG_ON(msg != NULL && msg->number != get); 1964 DBUG_ON(msg != NULL && msg->number != get);
1968 DBUG_ON(msg != NULL && (msg->flags & XPC_M_DONE)); 1965 DBUG_ON(msg != NULL && (msg->flags & XPC_M_SN2_DONE));
1969 DBUG_ON(msg != NULL && !(msg->flags & XPC_M_READY)); 1966 DBUG_ON(msg != NULL && !(msg->flags & XPC_M_SN2_READY));
1970 1967
1968 payload = &msg->payload;
1971 break; 1969 break;
1972 } 1970 }
1973 1971
1974 } while (1); 1972 } while (1);
1975 1973
1976 return msg; 1974 return payload;
1977} 1975}
1978 1976
1979/* 1977/*
@@ -1985,7 +1983,7 @@ static void
1985xpc_send_msgs_sn2(struct xpc_channel *ch, s64 initial_put) 1983xpc_send_msgs_sn2(struct xpc_channel *ch, s64 initial_put)
1986{ 1984{
1987 struct xpc_channel_sn2 *ch_sn2 = &ch->sn.sn2; 1985 struct xpc_channel_sn2 *ch_sn2 = &ch->sn.sn2;
1988 struct xpc_msg *msg; 1986 struct xpc_msg_sn2 *msg;
1989 s64 put = initial_put + 1; 1987 s64 put = initial_put + 1;
1990 int send_msgrequest = 0; 1988 int send_msgrequest = 0;
1991 1989
@@ -1995,11 +1993,12 @@ xpc_send_msgs_sn2(struct xpc_channel *ch, s64 initial_put)
1995 if (put == ch_sn2->w_local_GP.put) 1993 if (put == ch_sn2->w_local_GP.put)
1996 break; 1994 break;
1997 1995
1998 msg = (struct xpc_msg *)((u64)ch_sn2->local_msgqueue + 1996 msg = (struct xpc_msg_sn2 *)((u64)ch_sn2->
1999 (put % ch->local_nentries) * 1997 local_msgqueue + (put %
2000 ch->msg_size); 1998 ch->local_nentries) *
1999 ch->entry_size);
2001 2000
2002 if (!(msg->flags & XPC_M_READY)) 2001 if (!(msg->flags & XPC_M_SN2_READY))
2003 break; 2002 break;
2004 2003
2005 put++; 2004 put++;
@@ -2026,7 +2025,7 @@ xpc_send_msgs_sn2(struct xpc_channel *ch, s64 initial_put)
2026 2025
2027 /* 2026 /*
2028 * We need to ensure that the message referenced by 2027 * We need to ensure that the message referenced by
2029 * local_GP->put is not XPC_M_READY or that local_GP->put 2028 * local_GP->put is not XPC_M_SN2_READY or that local_GP->put
2030 * equals w_local_GP.put, so we'll go have a look. 2029 * equals w_local_GP.put, so we'll go have a look.
2031 */ 2030 */
2032 initial_put = put; 2031 initial_put = put;
@@ -2042,10 +2041,10 @@ xpc_send_msgs_sn2(struct xpc_channel *ch, s64 initial_put)
2042 */ 2041 */
2043static enum xp_retval 2042static enum xp_retval
2044xpc_allocate_msg_sn2(struct xpc_channel *ch, u32 flags, 2043xpc_allocate_msg_sn2(struct xpc_channel *ch, u32 flags,
2045 struct xpc_msg **address_of_msg) 2044 struct xpc_msg_sn2 **address_of_msg)
2046{ 2045{
2047 struct xpc_channel_sn2 *ch_sn2 = &ch->sn.sn2; 2046 struct xpc_channel_sn2 *ch_sn2 = &ch->sn.sn2;
2048 struct xpc_msg *msg; 2047 struct xpc_msg_sn2 *msg;
2049 enum xp_retval ret; 2048 enum xp_retval ret;
2050 s64 put; 2049 s64 put;
2051 2050
@@ -2097,8 +2096,9 @@ xpc_allocate_msg_sn2(struct xpc_channel *ch, u32 flags,
2097 } 2096 }
2098 2097
2099 /* get the message's address and initialize it */ 2098 /* get the message's address and initialize it */
2100 msg = (struct xpc_msg *)((u64)ch_sn2->local_msgqueue + 2099 msg = (struct xpc_msg_sn2 *)((u64)ch_sn2->local_msgqueue +
2101 (put % ch->local_nentries) * ch->msg_size); 2100 (put % ch->local_nentries) *
2101 ch->entry_size);
2102 2102
2103 DBUG_ON(msg->flags != 0); 2103 DBUG_ON(msg->flags != 0);
2104 msg->number = put; 2104 msg->number = put;
@@ -2117,20 +2117,20 @@ xpc_allocate_msg_sn2(struct xpc_channel *ch, u32 flags,
2117 * partition the message is being sent to. 2117 * partition the message is being sent to.
2118 */ 2118 */
2119static enum xp_retval 2119static enum xp_retval
2120xpc_send_msg_sn2(struct xpc_channel *ch, u32 flags, void *payload, 2120xpc_send_payload_sn2(struct xpc_channel *ch, u32 flags, void *payload,
2121 u16 payload_size, u8 notify_type, xpc_notify_func func, 2121 u16 payload_size, u8 notify_type, xpc_notify_func func,
2122 void *key) 2122 void *key)
2123{ 2123{
2124 enum xp_retval ret = xpSuccess; 2124 enum xp_retval ret = xpSuccess;
2125 struct xpc_channel_sn2 *ch_sn2 = &ch->sn.sn2; 2125 struct xpc_channel_sn2 *ch_sn2 = &ch->sn.sn2;
2126 struct xpc_msg *msg = msg; 2126 struct xpc_msg_sn2 *msg = msg;
2127 struct xpc_notify *notify = notify; 2127 struct xpc_notify_sn2 *notify = notify;
2128 s64 msg_number; 2128 s64 msg_number;
2129 s64 put; 2129 s64 put;
2130 2130
2131 DBUG_ON(notify_type == XPC_N_CALL && func == NULL); 2131 DBUG_ON(notify_type == XPC_N_CALL && func == NULL);
2132 2132
2133 if (XPC_MSG_SIZE(payload_size) > ch->msg_size) 2133 if (XPC_MSG_SIZE(payload_size) > ch->entry_size)
2134 return xpPayloadTooBig; 2134 return xpPayloadTooBig;
2135 2135
2136 xpc_msgqueue_ref(ch); 2136 xpc_msgqueue_ref(ch);
@@ -2155,7 +2155,7 @@ xpc_send_msg_sn2(struct xpc_channel *ch, u32 flags, void *payload,
2155 * Tell the remote side to send an ACK interrupt when the 2155 * Tell the remote side to send an ACK interrupt when the
2156 * message has been delivered. 2156 * message has been delivered.
2157 */ 2157 */
2158 msg->flags |= XPC_M_INTERRUPT; 2158 msg->flags |= XPC_M_SN2_INTERRUPT;
2159 2159
2160 atomic_inc(&ch->n_to_notify); 2160 atomic_inc(&ch->n_to_notify);
2161 2161
@@ -2185,7 +2185,7 @@ xpc_send_msg_sn2(struct xpc_channel *ch, u32 flags, void *payload,
2185 2185
2186 memcpy(&msg->payload, payload, payload_size); 2186 memcpy(&msg->payload, payload, payload_size);
2187 2187
2188 msg->flags |= XPC_M_READY; 2188 msg->flags |= XPC_M_SN2_READY;
2189 2189
2190 /* 2190 /*
2191 * The preceding store of msg->flags must occur before the following 2191 * The preceding store of msg->flags must occur before the following
@@ -2208,12 +2208,15 @@ out_1:
2208 * Now we actually acknowledge the messages that have been delivered and ack'd 2208 * Now we actually acknowledge the messages that have been delivered and ack'd
2209 * by advancing the cached remote message queue's Get value and if requested 2209 * by advancing the cached remote message queue's Get value and if requested
2210 * send a chctl msgrequest to the message sender's partition. 2210 * send a chctl msgrequest to the message sender's partition.
2211 *
2212 * If a message has XPC_M_SN2_INTERRUPT set, send an interrupt to the partition
2213 * that sent the message.
2211 */ 2214 */
2212static void 2215static void
2213xpc_acknowledge_msgs_sn2(struct xpc_channel *ch, s64 initial_get, u8 msg_flags) 2216xpc_acknowledge_msgs_sn2(struct xpc_channel *ch, s64 initial_get, u8 msg_flags)
2214{ 2217{
2215 struct xpc_channel_sn2 *ch_sn2 = &ch->sn.sn2; 2218 struct xpc_channel_sn2 *ch_sn2 = &ch->sn.sn2;
2216 struct xpc_msg *msg; 2219 struct xpc_msg_sn2 *msg;
2217 s64 get = initial_get + 1; 2220 s64 get = initial_get + 1;
2218 int send_msgrequest = 0; 2221 int send_msgrequest = 0;
2219 2222
@@ -2223,11 +2226,12 @@ xpc_acknowledge_msgs_sn2(struct xpc_channel *ch, s64 initial_get, u8 msg_flags)
2223 if (get == ch_sn2->w_local_GP.get) 2226 if (get == ch_sn2->w_local_GP.get)
2224 break; 2227 break;
2225 2228
2226 msg = (struct xpc_msg *)((u64)ch_sn2->remote_msgqueue + 2229 msg = (struct xpc_msg_sn2 *)((u64)ch_sn2->
2227 (get % ch->remote_nentries) * 2230 remote_msgqueue + (get %
2228 ch->msg_size); 2231 ch->remote_nentries) *
2232 ch->entry_size);
2229 2233
2230 if (!(msg->flags & XPC_M_DONE)) 2234 if (!(msg->flags & XPC_M_SN2_DONE))
2231 break; 2235 break;
2232 2236
2233 msg_flags |= msg->flags; 2237 msg_flags |= msg->flags;
@@ -2251,11 +2255,11 @@ xpc_acknowledge_msgs_sn2(struct xpc_channel *ch, s64 initial_get, u8 msg_flags)
2251 dev_dbg(xpc_chan, "local_GP->get changed to %ld, partid=%d, " 2255 dev_dbg(xpc_chan, "local_GP->get changed to %ld, partid=%d, "
2252 "channel=%d\n", get, ch->partid, ch->number); 2256 "channel=%d\n", get, ch->partid, ch->number);
2253 2257
2254 send_msgrequest = (msg_flags & XPC_M_INTERRUPT); 2258 send_msgrequest = (msg_flags & XPC_M_SN2_INTERRUPT);
2255 2259
2256 /* 2260 /*
2257 * We need to ensure that the message referenced by 2261 * We need to ensure that the message referenced by
2258 * local_GP->get is not XPC_M_DONE or that local_GP->get 2262 * local_GP->get is not XPC_M_SN2_DONE or that local_GP->get
2259 * equals w_local_GP.get, so we'll go have a look. 2263 * equals w_local_GP.get, so we'll go have a look.
2260 */ 2264 */
2261 initial_get = get; 2265 initial_get = get;
@@ -2266,19 +2270,23 @@ xpc_acknowledge_msgs_sn2(struct xpc_channel *ch, s64 initial_get, u8 msg_flags)
2266} 2270}
2267 2271
2268static void 2272static void
2269xpc_received_msg_sn2(struct xpc_channel *ch, struct xpc_msg *msg) 2273xpc_received_payload_sn2(struct xpc_channel *ch, void *payload)
2270{ 2274{
2275 struct xpc_msg_sn2 *msg;
2276 s64 msg_number;
2271 s64 get; 2277 s64 get;
2272 s64 msg_number = msg->number; 2278
2279 msg = container_of(payload, struct xpc_msg_sn2, payload);
2280 msg_number = msg->number;
2273 2281
2274 dev_dbg(xpc_chan, "msg=0x%p, msg_number=%ld, partid=%d, channel=%d\n", 2282 dev_dbg(xpc_chan, "msg=0x%p, msg_number=%ld, partid=%d, channel=%d\n",
2275 (void *)msg, msg_number, ch->partid, ch->number); 2283 (void *)msg, msg_number, ch->partid, ch->number);
2276 2284
2277 DBUG_ON((((u64)msg - (u64)ch->remote_msgqueue) / ch->msg_size) != 2285 DBUG_ON((((u64)msg - (u64)ch->remote_msgqueue) / ch->entry_size) !=
2278 msg_number % ch->remote_nentries); 2286 msg_number % ch->remote_nentries);
2279 DBUG_ON(msg->flags & XPC_M_DONE); 2287 DBUG_ON(msg->flags & XPC_M_SN2_DONE);
2280 2288
2281 msg->flags |= XPC_M_DONE; 2289 msg->flags |= XPC_M_SN2_DONE;
2282 2290
2283 /* 2291 /*
2284 * The preceding store of msg->flags must occur before the following 2292 * The preceding store of msg->flags must occur before the following
@@ -2337,8 +2345,8 @@ xpc_init_sn2(void)
2337 2345
2338 xpc_notify_senders_of_disconnect = xpc_notify_senders_of_disconnect_sn2; 2346 xpc_notify_senders_of_disconnect = xpc_notify_senders_of_disconnect_sn2;
2339 xpc_process_msg_chctl_flags = xpc_process_msg_chctl_flags_sn2; 2347 xpc_process_msg_chctl_flags = xpc_process_msg_chctl_flags_sn2;
2340 xpc_n_of_deliverable_msgs = xpc_n_of_deliverable_msgs_sn2; 2348 xpc_n_of_deliverable_payloads = xpc_n_of_deliverable_payloads_sn2;
2341 xpc_get_deliverable_msg = xpc_get_deliverable_msg_sn2; 2349 xpc_get_deliverable_payload = xpc_get_deliverable_payload_sn2;
2342 2350
2343 xpc_indicate_partition_engaged = xpc_indicate_partition_engaged_sn2; 2351 xpc_indicate_partition_engaged = xpc_indicate_partition_engaged_sn2;
2344 xpc_indicate_partition_disengaged = 2352 xpc_indicate_partition_disengaged =
@@ -2347,8 +2355,14 @@ xpc_init_sn2(void)
2347 xpc_any_partition_engaged = xpc_any_partition_engaged_sn2; 2355 xpc_any_partition_engaged = xpc_any_partition_engaged_sn2;
2348 xpc_assume_partition_disengaged = xpc_assume_partition_disengaged_sn2; 2356 xpc_assume_partition_disengaged = xpc_assume_partition_disengaged_sn2;
2349 2357
2350 xpc_send_msg = xpc_send_msg_sn2; 2358 xpc_send_payload = xpc_send_payload_sn2;
2351 xpc_received_msg = xpc_received_msg_sn2; 2359 xpc_received_payload = xpc_received_payload_sn2;
2360
2361 if (offsetof(struct xpc_msg_sn2, payload) > XPC_MSG_HDR_MAX_SIZE) {
2362 dev_err(xpc_part, "header portion of struct xpc_msg_sn2 is "
2363 "larger than %d\n", XPC_MSG_HDR_MAX_SIZE);
2364 return -E2BIG;
2365 }
2352 2366
2353 buf_size = max(XPC_RP_VARS_SIZE, 2367 buf_size = max(XPC_RP_VARS_SIZE,
2354 XPC_RP_HEADER_SIZE + XP_NASID_MASK_BYTES_SN2); 2368 XPC_RP_HEADER_SIZE + XP_NASID_MASK_BYTES_SN2);