arch/tile: fix hardwall for tilegx and generalize for idn and ipi
The hardwall drain code was not properly implemented for tilegx, just tilepro, so you couldn't reliably restart an application that made use of the udn. In addition, the code was only applicable to the udn (user dynamic network). On tilegx there is a second user network that is available (the "idn"), and there is support for having I/O shims deliver user-level interrupts to applications ("ipi") which functions in a very similar way to the inter-core permissions used for udn/idn. So this change also generalizes the code from supporting just the udn to supports udn/idn/ipi on tilegx. By default we now use /dev/hardwall/{udn,idn,ipi} with separate minor numbers for the three devices. Signed-off-by: Chris Metcalf <cmetcalf@tilera.com>
This commit is contained in:
parent
621b195515
commit
b8ace0833f
|
@ -65,6 +65,31 @@
|
|||
#define SPR_EX_CONTEXT_2_1__ICS_RMASK 0x1
|
||||
#define SPR_EX_CONTEXT_2_1__ICS_MASK 0x4
|
||||
#define SPR_FAIL 0x4e09
|
||||
#define SPR_IDN_AVAIL_EN 0x3e05
|
||||
#define SPR_IDN_CA_DATA 0x0b00
|
||||
#define SPR_IDN_DATA_AVAIL 0x0b03
|
||||
#define SPR_IDN_DEADLOCK_TIMEOUT 0x3406
|
||||
#define SPR_IDN_DEMUX_CA_COUNT 0x0a05
|
||||
#define SPR_IDN_DEMUX_COUNT_0 0x0a06
|
||||
#define SPR_IDN_DEMUX_COUNT_1 0x0a07
|
||||
#define SPR_IDN_DEMUX_CTL 0x0a08
|
||||
#define SPR_IDN_DEMUX_QUEUE_SEL 0x0a0a
|
||||
#define SPR_IDN_DEMUX_STATUS 0x0a0b
|
||||
#define SPR_IDN_DEMUX_WRITE_FIFO 0x0a0c
|
||||
#define SPR_IDN_DIRECTION_PROTECT 0x2e05
|
||||
#define SPR_IDN_PENDING 0x0a0e
|
||||
#define SPR_IDN_REFILL_EN 0x0e05
|
||||
#define SPR_IDN_SP_FIFO_DATA 0x0a0f
|
||||
#define SPR_IDN_SP_FIFO_SEL 0x0a10
|
||||
#define SPR_IDN_SP_FREEZE 0x0a11
|
||||
#define SPR_IDN_SP_FREEZE__SP_FRZ_MASK 0x1
|
||||
#define SPR_IDN_SP_FREEZE__DEMUX_FRZ_MASK 0x2
|
||||
#define SPR_IDN_SP_FREEZE__NON_DEST_EXT_MASK 0x4
|
||||
#define SPR_IDN_SP_STATE 0x0a12
|
||||
#define SPR_IDN_TAG_0 0x0a13
|
||||
#define SPR_IDN_TAG_1 0x0a14
|
||||
#define SPR_IDN_TAG_VALID 0x0a15
|
||||
#define SPR_IDN_TILE_COORD 0x0a16
|
||||
#define SPR_INTCTRL_0_STATUS 0x4a07
|
||||
#define SPR_INTCTRL_1_STATUS 0x4807
|
||||
#define SPR_INTCTRL_2_STATUS 0x4607
|
||||
|
@ -87,12 +112,36 @@
|
|||
#define SPR_INTERRUPT_MASK_SET_1_1 0x480e
|
||||
#define SPR_INTERRUPT_MASK_SET_2_0 0x460c
|
||||
#define SPR_INTERRUPT_MASK_SET_2_1 0x460d
|
||||
#define SPR_MPL_AUX_PERF_COUNT_SET_0 0x6000
|
||||
#define SPR_MPL_AUX_PERF_COUNT_SET_1 0x6001
|
||||
#define SPR_MPL_AUX_PERF_COUNT_SET_2 0x6002
|
||||
#define SPR_MPL_DMA_CPL_SET_0 0x5800
|
||||
#define SPR_MPL_DMA_CPL_SET_1 0x5801
|
||||
#define SPR_MPL_DMA_CPL_SET_2 0x5802
|
||||
#define SPR_MPL_DMA_NOTIFY_SET_0 0x3800
|
||||
#define SPR_MPL_DMA_NOTIFY_SET_1 0x3801
|
||||
#define SPR_MPL_DMA_NOTIFY_SET_2 0x3802
|
||||
#define SPR_MPL_IDN_ACCESS_SET_0 0x0a00
|
||||
#define SPR_MPL_IDN_ACCESS_SET_1 0x0a01
|
||||
#define SPR_MPL_IDN_ACCESS_SET_2 0x0a02
|
||||
#define SPR_MPL_IDN_AVAIL_SET_0 0x3e00
|
||||
#define SPR_MPL_IDN_AVAIL_SET_1 0x3e01
|
||||
#define SPR_MPL_IDN_AVAIL_SET_2 0x3e02
|
||||
#define SPR_MPL_IDN_CA_SET_0 0x3a00
|
||||
#define SPR_MPL_IDN_CA_SET_1 0x3a01
|
||||
#define SPR_MPL_IDN_CA_SET_2 0x3a02
|
||||
#define SPR_MPL_IDN_COMPLETE_SET_0 0x1200
|
||||
#define SPR_MPL_IDN_COMPLETE_SET_1 0x1201
|
||||
#define SPR_MPL_IDN_COMPLETE_SET_2 0x1202
|
||||
#define SPR_MPL_IDN_FIREWALL_SET_0 0x2e00
|
||||
#define SPR_MPL_IDN_FIREWALL_SET_1 0x2e01
|
||||
#define SPR_MPL_IDN_FIREWALL_SET_2 0x2e02
|
||||
#define SPR_MPL_IDN_REFILL_SET_0 0x0e00
|
||||
#define SPR_MPL_IDN_REFILL_SET_1 0x0e01
|
||||
#define SPR_MPL_IDN_REFILL_SET_2 0x0e02
|
||||
#define SPR_MPL_IDN_TIMER_SET_0 0x3400
|
||||
#define SPR_MPL_IDN_TIMER_SET_1 0x3401
|
||||
#define SPR_MPL_IDN_TIMER_SET_2 0x3402
|
||||
#define SPR_MPL_INTCTRL_0_SET_0 0x4a00
|
||||
#define SPR_MPL_INTCTRL_0_SET_1 0x4a01
|
||||
#define SPR_MPL_INTCTRL_0_SET_2 0x4a02
|
||||
|
@ -102,6 +151,9 @@
|
|||
#define SPR_MPL_INTCTRL_2_SET_0 0x4600
|
||||
#define SPR_MPL_INTCTRL_2_SET_1 0x4601
|
||||
#define SPR_MPL_INTCTRL_2_SET_2 0x4602
|
||||
#define SPR_MPL_PERF_COUNT_SET_0 0x4200
|
||||
#define SPR_MPL_PERF_COUNT_SET_1 0x4201
|
||||
#define SPR_MPL_PERF_COUNT_SET_2 0x4202
|
||||
#define SPR_MPL_SN_ACCESS_SET_0 0x0800
|
||||
#define SPR_MPL_SN_ACCESS_SET_1 0x0801
|
||||
#define SPR_MPL_SN_ACCESS_SET_2 0x0802
|
||||
|
@ -181,6 +233,7 @@
|
|||
#define SPR_UDN_DEMUX_STATUS 0x0c0d
|
||||
#define SPR_UDN_DEMUX_WRITE_FIFO 0x0c0e
|
||||
#define SPR_UDN_DIRECTION_PROTECT 0x3005
|
||||
#define SPR_UDN_PENDING 0x0c10
|
||||
#define SPR_UDN_REFILL_EN 0x1005
|
||||
#define SPR_UDN_SP_FIFO_DATA 0x0c11
|
||||
#define SPR_UDN_SP_FIFO_SEL 0x0c12
|
||||
|
@ -195,6 +248,9 @@
|
|||
#define SPR_UDN_TAG_3 0x0c18
|
||||
#define SPR_UDN_TAG_VALID 0x0c19
|
||||
#define SPR_UDN_TILE_COORD 0x0c1a
|
||||
#define SPR_WATCH_CTL 0x4209
|
||||
#define SPR_WATCH_MASK 0x420a
|
||||
#define SPR_WATCH_VAL 0x420b
|
||||
|
||||
#endif /* !defined(__ARCH_SPR_DEF_H__) */
|
||||
|
||||
|
|
|
@ -52,6 +52,13 @@
|
|||
#define SPR_EX_CONTEXT_2_1__ICS_RMASK 0x1
|
||||
#define SPR_EX_CONTEXT_2_1__ICS_MASK 0x4
|
||||
#define SPR_FAIL 0x2707
|
||||
#define SPR_IDN_AVAIL_EN 0x1a05
|
||||
#define SPR_IDN_DATA_AVAIL 0x0a80
|
||||
#define SPR_IDN_DEADLOCK_TIMEOUT 0x1806
|
||||
#define SPR_IDN_DEMUX_COUNT_0 0x0a05
|
||||
#define SPR_IDN_DEMUX_COUNT_1 0x0a06
|
||||
#define SPR_IDN_DIRECTION_PROTECT 0x1405
|
||||
#define SPR_IDN_PENDING 0x0a08
|
||||
#define SPR_ILL_TRANS_REASON__I_STREAM_VA_RMASK 0x1
|
||||
#define SPR_INTCTRL_0_STATUS 0x2505
|
||||
#define SPR_INTCTRL_1_STATUS 0x2405
|
||||
|
@ -88,9 +95,27 @@
|
|||
#define SPR_IPI_MASK_SET_0 0x1f0a
|
||||
#define SPR_IPI_MASK_SET_1 0x1e0a
|
||||
#define SPR_IPI_MASK_SET_2 0x1d0a
|
||||
#define SPR_MPL_AUX_PERF_COUNT_SET_0 0x2100
|
||||
#define SPR_MPL_AUX_PERF_COUNT_SET_1 0x2101
|
||||
#define SPR_MPL_AUX_PERF_COUNT_SET_2 0x2102
|
||||
#define SPR_MPL_AUX_TILE_TIMER_SET_0 0x1700
|
||||
#define SPR_MPL_AUX_TILE_TIMER_SET_1 0x1701
|
||||
#define SPR_MPL_AUX_TILE_TIMER_SET_2 0x1702
|
||||
#define SPR_MPL_IDN_ACCESS_SET_0 0x0a00
|
||||
#define SPR_MPL_IDN_ACCESS_SET_1 0x0a01
|
||||
#define SPR_MPL_IDN_ACCESS_SET_2 0x0a02
|
||||
#define SPR_MPL_IDN_AVAIL_SET_0 0x1a00
|
||||
#define SPR_MPL_IDN_AVAIL_SET_1 0x1a01
|
||||
#define SPR_MPL_IDN_AVAIL_SET_2 0x1a02
|
||||
#define SPR_MPL_IDN_COMPLETE_SET_0 0x0500
|
||||
#define SPR_MPL_IDN_COMPLETE_SET_1 0x0501
|
||||
#define SPR_MPL_IDN_COMPLETE_SET_2 0x0502
|
||||
#define SPR_MPL_IDN_FIREWALL_SET_0 0x1400
|
||||
#define SPR_MPL_IDN_FIREWALL_SET_1 0x1401
|
||||
#define SPR_MPL_IDN_FIREWALL_SET_2 0x1402
|
||||
#define SPR_MPL_IDN_TIMER_SET_0 0x1800
|
||||
#define SPR_MPL_IDN_TIMER_SET_1 0x1801
|
||||
#define SPR_MPL_IDN_TIMER_SET_2 0x1802
|
||||
#define SPR_MPL_INTCTRL_0_SET_0 0x2500
|
||||
#define SPR_MPL_INTCTRL_0_SET_1 0x2501
|
||||
#define SPR_MPL_INTCTRL_0_SET_2 0x2502
|
||||
|
@ -100,6 +125,21 @@
|
|||
#define SPR_MPL_INTCTRL_2_SET_0 0x2300
|
||||
#define SPR_MPL_INTCTRL_2_SET_1 0x2301
|
||||
#define SPR_MPL_INTCTRL_2_SET_2 0x2302
|
||||
#define SPR_MPL_IPI_0 0x1f04
|
||||
#define SPR_MPL_IPI_0_SET_0 0x1f00
|
||||
#define SPR_MPL_IPI_0_SET_1 0x1f01
|
||||
#define SPR_MPL_IPI_0_SET_2 0x1f02
|
||||
#define SPR_MPL_IPI_1 0x1e04
|
||||
#define SPR_MPL_IPI_1_SET_0 0x1e00
|
||||
#define SPR_MPL_IPI_1_SET_1 0x1e01
|
||||
#define SPR_MPL_IPI_1_SET_2 0x1e02
|
||||
#define SPR_MPL_IPI_2 0x1d04
|
||||
#define SPR_MPL_IPI_2_SET_0 0x1d00
|
||||
#define SPR_MPL_IPI_2_SET_1 0x1d01
|
||||
#define SPR_MPL_IPI_2_SET_2 0x1d02
|
||||
#define SPR_MPL_PERF_COUNT_SET_0 0x2000
|
||||
#define SPR_MPL_PERF_COUNT_SET_1 0x2001
|
||||
#define SPR_MPL_PERF_COUNT_SET_2 0x2002
|
||||
#define SPR_MPL_UDN_ACCESS_SET_0 0x0b00
|
||||
#define SPR_MPL_UDN_ACCESS_SET_1 0x0b01
|
||||
#define SPR_MPL_UDN_ACCESS_SET_2 0x0b02
|
||||
|
@ -167,6 +207,9 @@
|
|||
#define SPR_UDN_DEMUX_COUNT_2 0x0b07
|
||||
#define SPR_UDN_DEMUX_COUNT_3 0x0b08
|
||||
#define SPR_UDN_DIRECTION_PROTECT 0x1505
|
||||
#define SPR_UDN_PENDING 0x0b0a
|
||||
#define SPR_WATCH_MASK 0x200a
|
||||
#define SPR_WATCH_VAL 0x200b
|
||||
|
||||
#endif /* !defined(__ARCH_SPR_DEF_H__) */
|
||||
|
||||
|
|
|
@ -11,12 +11,14 @@
|
|||
* NON INFRINGEMENT. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* Provide methods for the HARDWALL_FILE for accessing the UDN.
|
||||
* Provide methods for access control of per-cpu resources like
|
||||
* UDN, IDN, or IPI.
|
||||
*/
|
||||
|
||||
#ifndef _ASM_TILE_HARDWALL_H
|
||||
#define _ASM_TILE_HARDWALL_H
|
||||
|
||||
#include <arch/chip.h>
|
||||
#include <linux/ioctl.h>
|
||||
|
||||
#define HARDWALL_IOCTL_BASE 0xa2
|
||||
|
@ -24,8 +26,9 @@
|
|||
/*
|
||||
* The HARDWALL_CREATE() ioctl is a macro with a "size" argument.
|
||||
* The resulting ioctl value is passed to the kernel in conjunction
|
||||
* with a pointer to a little-endian bitmask of cpus, which must be
|
||||
* physically in a rectangular configuration on the chip.
|
||||
* with a pointer to a standard kernel bitmask of cpus.
|
||||
* For network resources (UDN or IDN) the bitmask must physically
|
||||
* represent a rectangular configuration on the chip.
|
||||
* The "size" is the number of bytes of cpu mask data.
|
||||
*/
|
||||
#define _HARDWALL_CREATE 1
|
||||
|
@ -44,13 +47,7 @@
|
|||
#define HARDWALL_GET_ID \
|
||||
_IO(HARDWALL_IOCTL_BASE, _HARDWALL_GET_ID)
|
||||
|
||||
#ifndef __KERNEL__
|
||||
|
||||
/* This is the canonical name expected by userspace. */
|
||||
#define HARDWALL_FILE "/dev/hardwall"
|
||||
|
||||
#else
|
||||
|
||||
#ifdef __KERNEL__
|
||||
/* /proc hooks for hardwall. */
|
||||
struct proc_dir_entry;
|
||||
#ifdef CONFIG_HARDWALL
|
||||
|
@ -59,7 +56,6 @@ int proc_pid_hardwall(struct task_struct *task, char *buffer);
|
|||
#else
|
||||
static inline void proc_tile_hardwall_init(struct proc_dir_entry *root) {}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* _ASM_TILE_HARDWALL_H */
|
||||
|
|
|
@ -76,6 +76,17 @@ struct async_tlb {
|
|||
|
||||
#ifdef CONFIG_HARDWALL
|
||||
struct hardwall_info;
|
||||
struct hardwall_task {
|
||||
/* Which hardwall is this task tied to? (or NULL if none) */
|
||||
struct hardwall_info *info;
|
||||
/* Chains this task into the list at info->task_head. */
|
||||
struct list_head list;
|
||||
};
|
||||
#ifdef __tilepro__
|
||||
#define HARDWALL_TYPES 1 /* udn */
|
||||
#else
|
||||
#define HARDWALL_TYPES 3 /* udn, idn, and ipi */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
struct thread_struct {
|
||||
|
@ -116,10 +127,8 @@ struct thread_struct {
|
|||
unsigned long dstream_pf;
|
||||
#endif
|
||||
#ifdef CONFIG_HARDWALL
|
||||
/* Is this task tied to an activated hardwall? */
|
||||
struct hardwall_info *hardwall;
|
||||
/* Chains this task into the list at hardwall->list. */
|
||||
struct list_head hardwall_list;
|
||||
/* Hardwall information for various resources. */
|
||||
struct hardwall_task hardwall[HARDWALL_TYPES];
|
||||
#endif
|
||||
#if CHIP_HAS_TILE_DMA()
|
||||
/* Async DMA TLB fault information */
|
||||
|
|
|
@ -41,15 +41,15 @@ void restrict_dma_mpls(void);
|
|||
#ifdef CONFIG_HARDWALL
|
||||
/* User-level network management functions */
|
||||
void reset_network_state(void);
|
||||
void grant_network_mpls(void);
|
||||
void restrict_network_mpls(void);
|
||||
struct task_struct;
|
||||
int hardwall_deactivate(struct task_struct *task);
|
||||
void hardwall_switch_tasks(struct task_struct *prev, struct task_struct *next);
|
||||
void hardwall_deactivate_all(struct task_struct *task);
|
||||
int hardwall_ipi_valid(int cpu);
|
||||
|
||||
/* Hook hardwall code into changes in affinity. */
|
||||
#define arch_set_cpus_allowed(p, new_mask) do { \
|
||||
if (p->thread.hardwall && !cpumask_equal(&p->cpus_allowed, new_mask)) \
|
||||
hardwall_deactivate(p); \
|
||||
if (!cpumask_equal(&p->cpus_allowed, new_mask)) \
|
||||
hardwall_deactivate_all(p); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1257,7 +1257,7 @@ STD_ENTRY(fill_ra_stack)
|
|||
int_hand INT_UNALIGN_DATA, UNALIGN_DATA, int_unalign
|
||||
int_hand INT_DTLB_MISS, DTLB_MISS, do_page_fault
|
||||
int_hand INT_DTLB_ACCESS, DTLB_ACCESS, do_page_fault
|
||||
int_hand INT_IDN_FIREWALL, IDN_FIREWALL, bad_intr
|
||||
int_hand INT_IDN_FIREWALL, IDN_FIREWALL, do_hardwall_trap
|
||||
int_hand INT_UDN_FIREWALL, UDN_FIREWALL, do_hardwall_trap
|
||||
int_hand INT_TILE_TIMER, TILE_TIMER, do_timer_interrupt
|
||||
int_hand INT_IDN_TIMER, IDN_TIMER, bad_intr
|
||||
|
|
|
@ -145,10 +145,10 @@ void free_thread_info(struct thread_info *info)
|
|||
* Calling deactivate here just frees up the data structures.
|
||||
* If the task we're freeing held the last reference to a
|
||||
* hardwall fd, it would have been released prior to this point
|
||||
* anyway via exit_files(), and "hardwall" would be NULL by now.
|
||||
* anyway via exit_files(), and the hardwall_task.info pointers
|
||||
* would be NULL by now.
|
||||
*/
|
||||
if (info->task->thread.hardwall)
|
||||
hardwall_deactivate(info->task);
|
||||
hardwall_deactivate_all(info->task);
|
||||
#endif
|
||||
|
||||
if (step_state) {
|
||||
|
@ -264,7 +264,8 @@ int copy_thread(unsigned long clone_flags, unsigned long sp,
|
|||
|
||||
#ifdef CONFIG_HARDWALL
|
||||
/* New thread does not own any networks. */
|
||||
p->thread.hardwall = NULL;
|
||||
memset(&p->thread.hardwall[0], 0,
|
||||
sizeof(struct hardwall_task) * HARDWALL_TYPES);
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -534,12 +535,7 @@ struct task_struct *__sched _switch_to(struct task_struct *prev,
|
|||
|
||||
#ifdef CONFIG_HARDWALL
|
||||
/* Enable or disable access to the network registers appropriately. */
|
||||
if (prev->thread.hardwall != NULL) {
|
||||
if (next->thread.hardwall == NULL)
|
||||
restrict_network_mpls();
|
||||
} else if (next->thread.hardwall != NULL) {
|
||||
grant_network_mpls();
|
||||
}
|
||||
hardwall_switch_tasks(prev, next);
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in New Issue