source: mainline/uspace/lib/net/generic/packet_remote.c@ fbcdeb8

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since fbcdeb8 was fbcdeb8, checked in by Martin Decky <martin@…>, 14 years ago

Remove the two-phase way of creating virtual memory areas (first asking for a mappable address and then mapping it) which was prone to race conditions when two or more calls to as_get_mappable_page() and as_area_create() were interleaved. This for example caused the e1k driver to randomly fail.

The memory area related syscalls and IPC calls have all been altered to accept a special value (void *) -1, representing a demand to atomically search for a mappable address space "hole" and map to it.

Individual changes:

  • IPC_M_SHARE_OUT: the destination address space area is supplied by the kernel, the callee only specifies the lower bound

(the address is returned to the callee via a pointer in an IPC reply argument)

  • IPC_M_SHARE_IN: the destination address space ares is supplied by the kernel, the callee only specifies the lower bound

(the address is returned to the caller as usual via an IPC argument)

  • SYS_AS_GET_UNMAPPED_AREA was removed
  • dummy implementations of SYS_PHYSMEM_UNMAP and SYS_IOSPACE_DISABLE were added for the sake of symmetry (they do nothing yet)
  • SYS_PHYSMEM_MAP and SYS_DMAMEM_MAP were altered to accept (void *) -1 as address space area base and a lower bound
  • kernel as_area_create() and as_area_share() were altered to accept (void *) -1 as address space area base and a lower bound
  • uspace libraries and programs were altered to reflect the new API
  • Property mode set to 100644
File size: 6.4 KB
RevLine 
[21580dd]1/*
2 * Copyright (c) 2009 Lukas Mejdrech
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
[b69ceea]29/** @addtogroup libnet
30 * @{
[21580dd]31 */
32
33/** @file
[b69ceea]34 * Packet client interface implementation for remote modules.
35 * @see packet_client.h
[21580dd]36 */
37
38#include <async.h>
39#include <errno.h>
[d52fbaf]40#include <ipc/packet.h>
[21580dd]41#include <sys/mman.h>
42
[0a866eeb]43#include <packet_client.h>
44#include <packet_remote.h>
45
[c69d327]46#include <net/packet.h>
47#include <net/packet_header.h>
[21580dd]48
[14f1db0]49/** Obtain the packet from the packet server as the shared memory block.
50 *
51 * Create the local packet mapping as well.
52 *
[6b82009]53 * @param[in] sess Packet server module session.
54 * @param[out] packet Packet reference pointer to store the received
[14f1db0]55 * packet reference.
[6b82009]56 * @param[in] packet_id Packet identifier.
57 * @param[in] size Packet total size in bytes.
[14f1db0]58 *
59 * @return EOK on success.
60 * @return Other error codes as defined for the pm_add() function.
[6b82009]61 * @return Other error codes as defined for the async_share_in_start()
62 * function.
[14f1db0]63 *
[21580dd]64 */
[6b82009]65static int packet_return(async_sess_t *sess, packet_t **packet,
66 packet_id_t packet_id, size_t size)
[2fa0ad9]67{
[6b82009]68 async_exch_t *exch = async_exchange_begin(sess);
[aadf01e]69 ipc_call_t answer;
[6b82009]70 aid_t message = async_send_1(exch, NET_PACKET_GET, packet_id, &answer);
[fbcdeb8]71 int rc = async_share_in_start_0_0(exch, size, (void *) packet);
[6b82009]72 async_exchange_end(exch);
73
74 sysarg_t result;
75 async_wait_for(message, &result);
[0ab68f6]76
[8708be3b]77 if (rc != EOK)
[0ab68f6]78 return rc;
[6b82009]79
[fbcdeb8]80 if (packet == (void *) -1)
81 return ENOMEM;
82
[0ab68f6]83 rc = pm_add(*packet);
84 if (rc != EOK) {
85 munmap(*packet, size);
86 return rc;
[21580dd]87 }
[14f1db0]88
[21580dd]89 return result;
90}
91
[6b82009]92/** Translate the packet identifier to the packet reference.
93 *
94 * Try to find mapping first. The packet server is asked to share
95 * the packet if the mapping is not present.
96 *
97 * @param[in] sess Packet server module session.
98 * @param[out] packet Packet reference.
99 * @param[in] packet_id Packet identifier.
100 *
101 * @return EOK on success.
102 * @return EINVAL if the packet parameter is NULL.
103 * @return Other error codes as defined for the NET_PACKET_GET_SIZE
104 * message.
105 * @return Other error codes as defined for the packet_return()
106 * function.
107 *
[b69ceea]108 */
[6b82009]109int packet_translate_remote(async_sess_t *sess, packet_t **packet,
110 packet_id_t packet_id)
[14f1db0]111{
112 if (!packet)
113 return EINVAL;
114
115 *packet = pm_find(packet_id);
[49bd793b]116 if (*packet == NULL) {
[6b82009]117 async_exch_t *exch = async_exchange_begin(sess);
[96b02eb9]118 sysarg_t size;
[6b82009]119 int rc = async_req_1_1(exch, NET_PACKET_GET_SIZE, packet_id,
[0ab68f6]120 &size);
[6b82009]121 async_exchange_end(exch);
122
[0ab68f6]123 if (rc != EOK)
124 return rc;
[6b82009]125
126 rc = packet_return(sess, packet, packet_id, size);
[0ab68f6]127 if (rc != EOK)
128 return rc;
[14f1db0]129 }
[6b82009]130
[49bd793b]131 if ((*packet != NULL) && ((*packet)->next)) {
[46d4d9f]132 packet_t *next;
[6b82009]133 return packet_translate_remote(sess, &next, (*packet)->next);
[14f1db0]134 }
135
136 return EOK;
137}
[21580dd]138
[6b82009]139/** Obtain the packet of given dimensions.
140 *
141 * Contact the packet server to return the appropriate packet.
142 *
143 * @param[in] sess Packet server module session.
144 * @param[in] addr_len Source and destination addresses maximal length
145 * in bytes.
146 * @param[in] max_prefix Maximal prefix length in bytes.
147 * @param[in] max_content Maximal content length in bytes.
148 * @param[in] max_suffix Maximal suffix length in bytes.
149 *
150 * @return The packet reference.
151 * @return NULL on error.
152 *
[b69ceea]153 */
[6b82009]154packet_t *packet_get_4_remote(async_sess_t *sess, size_t max_content,
155 size_t addr_len, size_t max_prefix, size_t max_suffix)
[14f1db0]156{
[6b82009]157 async_exch_t *exch = async_exchange_begin(sess);
[96b02eb9]158 sysarg_t packet_id;
159 sysarg_t size;
[6b82009]160 int rc = async_req_4_2(exch, NET_PACKET_CREATE_4, max_content, addr_len,
[0ab68f6]161 max_prefix, max_suffix, &packet_id, &size);
[6b82009]162 async_exchange_end(exch);
163
[0ab68f6]164 if (rc != EOK)
[21580dd]165 return NULL;
[14f1db0]166
[46d4d9f]167 packet_t *packet = pm_find(packet_id);
[14f1db0]168 if (!packet) {
[6b82009]169 rc = packet_return(sess, &packet, packet_id, size);
[0ab68f6]170 if (rc != EOK)
[21580dd]171 return NULL;
172 }
[14f1db0]173
[21580dd]174 return packet;
175}
176
[6b82009]177/** Obtain the packet of given content size.
178 *
179 * Contact the packet server to return the appropriate packet.
[b69ceea]180 *
[6b82009]181 * @param[in] sess Packet server module session.
182 * @param[in] content Maximal content length in bytes.
183 *
184 * @return The packet reference.
185 * @return NULL on error.
[b69ceea]186 *
187 */
[6b82009]188packet_t *packet_get_1_remote(async_sess_t *sess, size_t content)
[14f1db0]189{
[6b82009]190 async_exch_t *exch = async_exchange_begin(sess);
[96b02eb9]191 sysarg_t packet_id;
192 sysarg_t size;
[6b82009]193 int rc = async_req_1_2(exch, NET_PACKET_CREATE_1, content, &packet_id,
[0ab68f6]194 &size);
[6b82009]195 async_exchange_end(exch);
196
[0ab68f6]197 if (rc != EOK)
[21580dd]198 return NULL;
[14f1db0]199
[46d4d9f]200 packet_t *packet = pm_find(packet_id);
[14f1db0]201 if (!packet) {
[6b82009]202 rc = packet_return(sess, &packet, packet_id, size);
[0ab68f6]203 if (rc != EOK)
[21580dd]204 return NULL;
205 }
[14f1db0]206
[21580dd]207 return packet;
208}
209
[6b82009]210/** Release the packet queue.
[b69ceea]211 *
212 * All packets in the queue are marked as free for use.
213 * The packet queue may be one packet only.
214 * The module should not use the packets after this point until they are
215 * received or obtained again.
216 *
[6b82009]217 * @param[in] sess Packet server module session.
218 * @param[in] packet_id Packet identifier.
219 *
[b69ceea]220 */
[6b82009]221void pq_release_remote(async_sess_t *sess, packet_id_t packet_id)
[14f1db0]222{
[6b82009]223 async_exch_t *exch = async_exchange_begin(sess);
224 async_msg_1(exch, NET_PACKET_RELEASE, packet_id);
225 async_exchange_end(exch);
[21580dd]226}
227
228/** @}
229 */
Note: See TracBrowser for help on using the repository browser.